dyno-table 2.0.0 → 2.0.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.
@@ -1,5 +1,5 @@
1
1
  import { DynamoItem } from './types.cjs';
2
- import { r as PrimaryKeyWithoutExpression } from './conditions-3ae5znV_.cjs';
2
+ import { r as PrimaryKeyWithoutExpression, s as Path } from './conditions-3ae5znV_.cjs';
3
3
  import { a as PutCommandParams, D as DeleteCommandParams } from './builder-types-BTVhQSHI.cjs';
4
4
 
5
5
  type BatchWriteOperation<T extends Record<string, unknown>> = {
@@ -87,7 +87,7 @@ declare class GetBuilder<T extends DynamoItem> {
87
87
  * @param fields - A single field name or an array of field names to return
88
88
  * @returns The builder instance for method chaining
89
89
  */
90
- select(fields: string | string[]): GetBuilder<T>;
90
+ select<K extends Path<T>>(fields: K | K[]): GetBuilder<T>;
91
91
  /**
92
92
  * Sets whether to use strongly consistent reads for the get operation.
93
93
  * Use this method when you need:
@@ -1,5 +1,5 @@
1
1
  import { DynamoItem } from './types.js';
2
- import { r as PrimaryKeyWithoutExpression } from './conditions-BtynAviC.js';
2
+ import { r as PrimaryKeyWithoutExpression, s as Path } from './conditions-BtynAviC.js';
3
3
  import { a as PutCommandParams, D as DeleteCommandParams } from './builder-types-CzuLR4Th.js';
4
4
 
5
5
  type BatchWriteOperation<T extends Record<string, unknown>> = {
@@ -87,7 +87,7 @@ declare class GetBuilder<T extends DynamoItem> {
87
87
  * @param fields - A single field name or an array of field names to return
88
88
  * @returns The builder instance for method chaining
89
89
  */
90
- select(fields: string | string[]): GetBuilder<T>;
90
+ select<K extends Path<T>>(fields: K | K[]): GetBuilder<T>;
91
91
  /**
92
92
  * Sets whether to use strongly consistent reads for the get operation.
93
93
  * Use this method when you need:
@@ -1,6 +1,6 @@
1
1
  import { r as PrimaryKeyWithoutExpression, C as Condition, q as ConditionOperator } from '../conditions-3ae5znV_.cjs';
2
2
  import { TransactionBuilder } from './transaction-builder.cjs';
3
- import { B as BatchBuilder } from '../batch-builder-CKYnMRyz.cjs';
3
+ import { B as BatchBuilder } from '../batch-builder-CzNAxWNT.cjs';
4
4
  import { D as DeleteCommandParams } from '../builder-types-BTVhQSHI.cjs';
5
5
  import { DynamoItem } from '../types.cjs';
6
6
  import '@aws-sdk/lib-dynamodb';
@@ -1,6 +1,6 @@
1
1
  import { r as PrimaryKeyWithoutExpression, C as Condition, q as ConditionOperator } from '../conditions-BtynAviC.js';
2
2
  import { TransactionBuilder } from './transaction-builder.js';
3
- import { B as BatchBuilder } from '../batch-builder-BOBwOIUE.js';
3
+ import { B as BatchBuilder } from '../batch-builder-TpkmiBp5.js';
4
4
  import { D as DeleteCommandParams } from '../builder-types-CzuLR4Th.js';
5
5
  import { DynamoItem } from '../types.js';
6
6
  import '@aws-sdk/lib-dynamodb';
@@ -1,6 +1,6 @@
1
1
  import { s as Path, t as PathType, C as Condition, q as ConditionOperator } from '../conditions-3ae5znV_.cjs';
2
2
  import { TransactionBuilder } from './transaction-builder.cjs';
3
- import { B as BatchBuilder } from '../batch-builder-CKYnMRyz.cjs';
3
+ import { B as BatchBuilder } from '../batch-builder-CzNAxWNT.cjs';
4
4
  import { a as PutCommandParams } from '../builder-types-BTVhQSHI.cjs';
5
5
  import { DynamoItem } from '../types.cjs';
6
6
  import '@aws-sdk/lib-dynamodb';
@@ -1,6 +1,6 @@
1
1
  import { s as Path, t as PathType, C as Condition, q as ConditionOperator } from '../conditions-BtynAviC.js';
2
2
  import { TransactionBuilder } from './transaction-builder.js';
3
- import { B as BatchBuilder } from '../batch-builder-BOBwOIUE.js';
3
+ import { B as BatchBuilder } from '../batch-builder-TpkmiBp5.js';
4
4
  import { a as PutCommandParams } from '../builder-types-CzuLR4Th.js';
5
5
  import { DynamoItem } from '../types.js';
6
6
  import '@aws-sdk/lib-dynamodb';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/conditions.ts","../../src/builders/paginator.ts","../../src/builders/filter-builder.ts","../../src/builders/result-iterator.ts","../../src/builders/query-builder.ts"],"names":[],"mappings":"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","file":"query-builder.cjs","sourcesContent":["import type { Path, PathType } from \"./builders/types\";\nimport type { DynamoItem } from \"./types\";\n\n/**\n * Supported comparison operators for DynamoDB conditions.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html AWS DynamoDB - Comparison Operator Reference}\n *\n * - eq: Equals (=)\n * - ne: Not equals (≠ / <>)\n * - lt: Less than (<)\n * - lte: Less than or equal to (≤)\n * - gt: Greater than (>)\n * - gte: Greater than or equal to (≥)\n * - between: Between two values (inclusive)\n * - in: Checks if attribute value is in a list of values\n * - beginsWith: Checks if string attribute begins with specified substring\n * - contains: Checks if string/set attribute contains specified value\n * - attributeExists: Checks if attribute exists\n * - attributeNotExists: Checks if attribute does not exist\n */\nexport type ComparisonOperator =\n | \"eq\"\n | \"ne\"\n | \"lt\"\n | \"lte\"\n | \"gt\"\n | \"gte\"\n | \"between\"\n | \"in\"\n | \"beginsWith\"\n | \"contains\"\n | \"attributeExists\"\n | \"attributeNotExists\";\n\n/**\n * Logical operators for combining multiple conditions.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - Logical Operator Reference}\n *\n * - and: Evaluates to true if all conditions are true\n * - or: Evaluates to true if any condition is true\n * - not: Negate the result of a condition\n */\nexport type LogicalOperator = \"and\" | \"or\" | \"not\";\n\n/**\n * Represents a DynamoDB condition expression.\n * Can be either a comparison condition or a logical combination of conditions.\n *\n * @example\n * // Simple comparison condition\n * const condition: Condition = {\n * type: \"eq\",\n * attr: \"status\",\n * value: \"ACTIVE\"\n * };\n *\n * @example\n * // Logical combination of conditions\n * const condition: Condition = {\n * type: \"and\",\n * conditions: [\n * { type: \"eq\", attr: \"status\", value: \"ACTIVE\" },\n * { type: \"gt\", attr: \"age\", value: 5 }\n * ]\n * };\n */\nexport interface Condition {\n /** The type of condition (comparison or logical operator) */\n type: ComparisonOperator | LogicalOperator;\n /** The attribute name for comparison conditions */\n attr?: string;\n /** The value to compare against for comparison conditions */\n value?: unknown;\n /** Array of conditions for logical operators (and/or) */\n conditions?: Condition[];\n /** Single condition for the 'not' operator */\n condition?: Condition;\n}\n\n/**\n * Parameters used to build DynamoDB expression strings.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeNames.html Expression Attribute Names}\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeValues.html Expression Attribute Values}\n */\nexport interface ExpressionParams {\n /** Map of attribute name placeholders to actual attribute names */\n expressionAttributeNames: Record<string, string>;\n /** Map of value placeholders to actual values */\n expressionAttributeValues: DynamoItem;\n /** Counter for generating unique value placeholders */\n valueCounter: { count: number };\n}\n\n/**\n * Creates a comparison condition builder function for the specified operator.\n * @internal\n */\nexport const createComparisonCondition =\n (type: ComparisonOperator) =>\n (attr: string, value: unknown): Condition => ({\n type,\n attr,\n value,\n });\n\n/**\n * Creates an equals (=) condition\n * @example\n * eq(\"status\", \"ACTIVE\") // status = \"ACTIVE\"\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html}\n */\nexport const eq = createComparisonCondition(\"eq\");\n\n/**\n * Creates a not equals (≠) condition\n * @example\n * ne(\"status\", \"DELETED\") // status <> \"DELETED\"\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html}\n */\nexport const ne = createComparisonCondition(\"ne\");\n\n/**\n * Creates a less than (<) condition\n * @example\n * lt(\"age\", 18) // age < 18\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html}\n */\nexport const lt = createComparisonCondition(\"lt\");\n\n/**\n * Creates a less than or equal to (≤) condition\n * @example\n * lte(\"age\", 18) // age <= 18\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html}\n */\nexport const lte = createComparisonCondition(\"lte\");\n\n/**\n * Creates a greater than (>) condition\n * @example\n * gt(\"price\", 100) // price > 100\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html}\n */\nexport const gt = createComparisonCondition(\"gt\");\n\n/**\n * Creates a greater than or equal to (≥) condition\n * @example\n * gte(\"price\", 100) // price >= 100\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html}\n */\nexport const gte = createComparisonCondition(\"gte\");\n\n/**\n * Creates a between condition that checks if a value is within a range (inclusive)\n * @example\n * between(\"age\", 18, 65) // age BETWEEN 18 AND 65\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - BETWEEN}\n */\nexport const between = (attr: string, lower: unknown, upper: unknown): Condition => ({\n type: \"between\",\n attr,\n value: [lower, upper],\n});\n\n/**\n * Creates an in condition that checks if a value is in a list of values\n * @example\n * inArray(\"status\", [\"ACTIVE\", \"PENDING\", \"PROCESSING\"]) // status IN (\"ACTIVE\", \"PENDING\", \"PROCESSING\")\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - IN}\n */\nexport const inArray = (attr: string, values: unknown[]): Condition => ({\n type: \"in\",\n attr,\n value: values,\n});\n\n/**\n * Creates a begins_with condition that checks if a string attribute starts with a substring\n * @example\n * beginsWith(\"email\", \"@example.com\") // begins_with(email, \"@example.com\")\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - begins_with}\n */\nexport const beginsWith = createComparisonCondition(\"beginsWith\");\n\n/**\n * Creates a contains condition that checks if a string contains a substring or if a set contains an element\n * @example\n * contains(\"tags\", \"important\") // contains(tags, \"important\")\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - contains}\n */\nexport const contains = createComparisonCondition(\"contains\");\n\n/**\n * Creates a condition that checks if an attribute exists\n * @example\n * attributeExists(\"email\") // attribute_exists(email)\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - attribute_exists}\n */\nexport const attributeExists = (attr: string): Condition => ({\n type: \"attributeExists\",\n attr,\n});\n\n/**\n * Creates a condition that checks if an attribute does not exist\n * @example\n * attributeNotExists(\"deletedAt\") // attribute_not_exists(deletedAt)\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - attribute_not_exists}\n */\nexport const attributeNotExists = (attr: string): Condition => ({\n type: \"attributeNotExists\",\n attr,\n});\n\n// --- Logical Operators ---\n\n/**\n * Combines multiple conditions with AND operator\n * @example\n * and(\n * eq(\"status\", \"ACTIVE\"),\n * gt(\"age\", 18)\n * ) // status = \"ACTIVE\" AND age > 18\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - AND}\n */\nexport const and = (...conditions: Condition[]): Condition => ({\n type: \"and\",\n conditions,\n});\n\n/**\n * Combines multiple conditions with OR operator\n * @example\n * or(\n * eq(\"status\", \"PENDING\"),\n * eq(\"status\", \"PROCESSING\")\n * ) // status = \"PENDING\" OR status = \"PROCESSING\"\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - OR}\n */\nexport const or = (...conditions: Condition[]): Condition => ({\n type: \"or\",\n conditions,\n});\n\n/**\n * Negates a condition\n * @example\n * not(eq(\"status\", \"DELETED\")) // NOT status = \"DELETED\"\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - NOT}\n */\nexport const not = (condition: Condition): Condition => ({\n type: \"not\",\n condition,\n});\n\n/**\n * Type-safe operators for building key conditions in DynamoDB queries.\n * Only includes operators that are valid for key conditions.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.KeyConditionExpressions AWS DynamoDB - Key Condition Expressions}\n *\n * @example\n * // Using with sort key conditions\n * table.query({\n * pk: \"USER#123\",\n * sk: op => op.beginsWith(\"ORDER#\")\n * })\n */\nexport type KeyConditionOperator = {\n /** Equals comparison for key attributes */\n eq: (value: unknown) => Condition;\n /** Less than comparison for key attributes */\n lt: (value: unknown) => Condition;\n /** Less than or equal comparison for key attributes */\n lte: (value: unknown) => Condition;\n /** Greater than comparison for key attributes */\n gt: (value: unknown) => Condition;\n /** Greater than or equal comparison for key attributes */\n gte: (value: unknown) => Condition;\n /** Between range comparison for key attributes */\n between: (lower: unknown, upper: unknown) => Condition;\n /** Begins with comparison for key attributes */\n beginsWith: (value: unknown) => Condition;\n /** Combines multiple key conditions with AND */\n and: (...conditions: Condition[]) => Condition;\n};\n\n/**\n * Type-safe operators for building conditions in DynamoDB operations.\n * Includes all available condition operators with proper type inference.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html AWS DynamoDB - Condition Expressions}\n *\n * @example\n * // Using with type-safe conditions\n * interface User {\n * status: string;\n * age: number;\n * email?: string;\n * }\n *\n * table.scan<User>()\n * .where(op => op.and(\n * op.eq(\"status\", \"ACTIVE\"),\n * op.gt(\"age\", 18),\n * op.attributeExists(\"email\")\n * ))\n *\n * @template T The type of the item being operated on\n */\nexport type ConditionOperator<T extends DynamoItem> = {\n /**\n * Creates an equals (=) condition for type-safe attribute comparison.\n * Tests if the specified attribute equals the provided value.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param value - The value to compare against (must match attribute type)\n * @returns A condition that evaluates to true when attr equals value\n *\n * @example\n * ```typescript\n * interface User { status: string; age: number; }\n *\n * // String comparison\n * op.eq(\"status\", \"ACTIVE\") // status = \"ACTIVE\"\n *\n * // Numeric comparison\n * op.eq(\"age\", 25) // age = 25\n *\n * // Nested attribute\n * op.eq(\"profile.role\", \"admin\") // profile.role = \"admin\"\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - Comparison Operators}\n */\n eq: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a not equals (≠ / <>) condition for type-safe attribute comparison.\n * Tests if the specified attribute does not equal the provided value.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param value - The value to compare against (must match attribute type)\n * @returns A condition that evaluates to true when attr does not equal value\n *\n * @example\n * ```typescript\n * interface User { status: string; priority: number; }\n *\n * // String comparison\n * op.ne(\"status\", \"DELETED\") // status <> \"DELETED\"\n *\n * // Numeric comparison\n * op.ne(\"priority\", 0) // priority <> 0\n *\n * // Useful for filtering out specific values\n * op.ne(\"category\", \"ARCHIVED\") // category <> \"ARCHIVED\"\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - Comparison Operators}\n */\n ne: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a less than (<) condition for type-safe attribute comparison.\n * Tests if the specified attribute is less than the provided value.\n * Works with numbers, strings (lexicographic), and dates.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param value - The value to compare against (must match attribute type)\n * @returns A condition that evaluates to true when attr is less than value\n *\n * @example\n * ```typescript\n * interface Product { price: number; name: string; createdAt: string; }\n *\n * // Numeric comparison\n * op.lt(\"price\", 100) // price < 100\n *\n * // String comparison (lexicographic)\n * op.lt(\"name\", \"M\") // name < \"M\" (names starting with A-L)\n *\n * // Date comparison (ISO strings)\n * op.lt(\"createdAt\", \"2024-01-01\") // createdAt < \"2024-01-01\"\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - Comparison Operators}\n */\n lt: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a less than or equal to (≤) condition for type-safe attribute comparison.\n * Tests if the specified attribute is less than or equal to the provided value.\n * Works with numbers, strings (lexicographic), and dates.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param value - The value to compare against (must match attribute type)\n * @returns A condition that evaluates to true when attr is less than or equal to value\n *\n * @example\n * ```typescript\n * interface Order { total: number; priority: number; dueDate: string; }\n *\n * // Numeric comparison\n * op.lte(\"total\", 1000) // total <= 1000\n *\n * // Priority levels\n * op.lte(\"priority\", 3) // priority <= 3 (low to medium priority)\n *\n * // Date deadlines\n * op.lte(\"dueDate\", \"2024-12-31\") // dueDate <= \"2024-12-31\"\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - Comparison Operators}\n */\n lte: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a greater than (>) condition for type-safe attribute comparison.\n * Tests if the specified attribute is greater than the provided value.\n * Works with numbers, strings (lexicographic), and dates.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param value - The value to compare against (must match attribute type)\n * @returns A condition that evaluates to true when attr is greater than value\n *\n * @example\n * ```typescript\n * interface User { age: number; score: number; lastLogin: string; }\n *\n * // Age restrictions\n * op.gt(\"age\", 18) // age > 18 (adults only)\n *\n * // Performance thresholds\n * op.gt(\"score\", 85) // score > 85 (high performers)\n *\n * // Recent activity\n * op.gt(\"lastLogin\", \"2024-01-01\") // lastLogin > \"2024-01-01\"\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - Comparison Operators}\n */\n gt: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a greater than or equal to (≥) condition for type-safe attribute comparison.\n * Tests if the specified attribute is greater than or equal to the provided value.\n * Works with numbers, strings (lexicographic), and dates.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param value - The value to compare against (must match attribute type)\n * @returns A condition that evaluates to true when attr is greater than or equal to value\n *\n * @example\n * ```typescript\n * interface Product { rating: number; version: string; releaseDate: string; }\n *\n * // Minimum ratings\n * op.gte(\"rating\", 4.0) // rating >= 4.0 (highly rated)\n *\n * // Version requirements\n * op.gte(\"version\", \"2.0.0\") // version >= \"2.0.0\"\n *\n * // Release date filters\n * op.gte(\"releaseDate\", \"2024-01-01\") // releaseDate >= \"2024-01-01\"\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - Comparison Operators}\n */\n gte: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a between condition for type-safe range comparison.\n * Tests if the specified attribute value falls within the inclusive range [lower, upper].\n * Works with numbers, strings (lexicographic), and dates.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param lower - The lower bound of the range (inclusive, must match attribute type)\n * @param upper - The upper bound of the range (inclusive, must match attribute type)\n * @returns A condition that evaluates to true when lower ≤ attr ≤ upper\n *\n * @example\n * ```typescript\n * interface Event { price: number; date: string; priority: number; }\n *\n * // Price range\n * op.between(\"price\", 50, 200) // price BETWEEN 50 AND 200\n *\n * // Date range\n * op.between(\"date\", \"2024-01-01\", \"2024-12-31\") // date BETWEEN \"2024-01-01\" AND \"2024-12-31\"\n *\n * // Priority levels\n * op.between(\"priority\", 1, 5) // priority BETWEEN 1 AND 5\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - BETWEEN}\n */\n between: <K extends Path<T>>(attr: K, lower: PathType<T, K>, upper: PathType<T, K>) => Condition;\n\n /**\n * Creates an IN condition for type-safe list membership testing.\n * Tests if the specified attribute value matches any value in the provided list.\n * Supports up to 100 values in the list as per DynamoDB limitations.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param values - Array of values to test against (must match attribute type, max 100 items)\n * @returns A condition that evaluates to true when attr matches any value in the list\n *\n * @example\n * ```typescript\n * interface User { status: string; role: string; priority: number; }\n *\n * // Status filtering\n * op.inArray(\"status\", [\"ACTIVE\", \"PENDING\", \"PROCESSING\"]) // status IN (\"ACTIVE\", \"PENDING\", \"PROCESSING\")\n *\n * // Role-based access\n * op.inArray(\"role\", [\"admin\", \"moderator\", \"editor\"]) // role IN (\"admin\", \"moderator\", \"editor\")\n *\n * // Priority levels\n * op.inArray(\"priority\", [1, 2, 3]) // priority IN (1, 2, 3)\n * ```\n *\n * @throws {Error} When values array is empty or contains more than 100 items\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - IN}\n */\n inArray: <K extends Path<T>>(attr: K, values: PathType<T, K>[]) => Condition;\n\n /**\n * Creates a begins_with condition for type-safe string prefix testing.\n * Tests if the specified string attribute starts with the provided substring.\n * Only works with string attributes - will fail on other data types.\n *\n * @param attr - The string attribute path to test (with full type safety)\n * @param value - The prefix string to test for (must match attribute type)\n * @returns A condition that evaluates to true when attr starts with value\n *\n * @example\n * ```typescript\n * interface User { email: string; name: string; id: string; }\n *\n * // Email domain filtering\n * op.beginsWith(\"email\", \"admin@\") // begins_with(email, \"admin@\")\n *\n * // Name prefix search\n * op.beginsWith(\"name\", \"John\") // begins_with(name, \"John\")\n *\n * // ID pattern matching\n * op.beginsWith(\"id\", \"USER#\") // begins_with(id, \"USER#\")\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - begins_with}\n */\n beginsWith: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a contains condition for type-safe substring or set membership testing.\n * For strings: tests if the attribute contains the specified substring.\n * For sets: tests if the set contains the specified element.\n *\n * @param attr - The attribute path to test (with full type safety)\n * @param value - The substring or element to search for (must match attribute type)\n * @returns A condition that evaluates to true when attr contains value\n *\n * @example\n * ```typescript\n * interface Post { content: string; tags: Set<string>; categories: string[]; }\n *\n * // Substring search in content\n * op.contains(\"content\", \"important\") // contains(content, \"important\")\n *\n * // Tag membership (for DynamoDB String Sets)\n * op.contains(\"tags\", \"featured\") // contains(tags, \"featured\")\n *\n * // Category search (for string arrays stored as lists)\n * op.contains(\"categories\", \"technology\") // contains(categories, \"technology\")\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - contains}\n */\n contains: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates an attribute_exists condition for type-safe attribute presence testing.\n * Tests if the specified attribute exists in the item, regardless of its value.\n * Useful for filtering items that have optional attributes populated.\n *\n * @param attr - The attribute path to test for existence (with full type safety)\n * @returns A condition that evaluates to true when the attribute exists\n *\n * @example\n * ```typescript\n * interface User { email: string; phone?: string; profile?: { avatar?: string; }; }\n *\n * // Check for optional fields\n * op.attributeExists(\"phone\") // attribute_exists(phone)\n *\n * // Check for nested optional attributes\n * op.attributeExists(\"profile.avatar\") // attribute_exists(profile.avatar)\n *\n * // Useful in combination with other conditions\n * op.and(\n * op.eq(\"status\", \"ACTIVE\"),\n * op.attributeExists(\"email\") // Only active users with email\n * )\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - attribute_exists}\n */\n attributeExists: <K extends Path<T>>(attr: K) => Condition;\n\n /**\n * Creates an attribute_not_exists condition for type-safe attribute absence testing.\n * Tests if the specified attribute does not exist in the item.\n * Useful for conditional writes to prevent overwriting existing data.\n *\n * @param attr - The attribute path to test for absence (with full type safety)\n * @returns A condition that evaluates to true when the attribute does not exist\n *\n * @example\n * ```typescript\n * interface User { id: string; email: string; deletedAt?: string; }\n *\n * // Ensure item hasn't been soft-deleted\n * op.attributeNotExists(\"deletedAt\") // attribute_not_exists(deletedAt)\n *\n * // Prevent duplicate creation\n * op.attributeNotExists(\"id\") // attribute_not_exists(id)\n *\n * // Conditional updates\n * op.and(\n * op.eq(\"status\", \"PENDING\"),\n * op.attributeNotExists(\"processedAt\") // Only unprocessed items\n * )\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - attribute_not_exists}\n */\n attributeNotExists: <K extends Path<T>>(attr: K) => Condition;\n\n /**\n * Combines multiple conditions with logical AND operator.\n * All provided conditions must evaluate to true for the AND condition to be true.\n * Supports any number of conditions as arguments.\n *\n * @param conditions - Variable number of conditions to combine with AND\n * @returns A condition that evaluates to true when all input conditions are true\n *\n * @example\n * ```typescript\n * interface User { status: string; age: number; role: string; verified: boolean; }\n *\n * // Multiple criteria\n * op.and(\n * op.eq(\"status\", \"ACTIVE\"),\n * op.gt(\"age\", 18),\n * op.eq(\"verified\", true)\n * ) // status = \"ACTIVE\" AND age > 18 AND verified = true\n *\n * // Complex business logic\n * op.and(\n * op.inArray(\"role\", [\"admin\", \"moderator\"]),\n * op.attributeExists(\"permissions\"),\n * op.ne(\"status\", \"SUSPENDED\")\n * )\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - AND}\n */\n and: (...conditions: Condition[]) => Condition;\n\n /**\n * Combines multiple conditions with logical OR operator.\n * At least one of the provided conditions must evaluate to true for the OR condition to be true.\n * Supports any number of conditions as arguments.\n *\n * @param conditions - Variable number of conditions to combine with OR\n * @returns A condition that evaluates to true when any input condition is true\n *\n * @example\n * ```typescript\n * interface Order { status: string; priority: string; urgent: boolean; }\n *\n * // Alternative statuses\n * op.or(\n * op.eq(\"status\", \"PENDING\"),\n * op.eq(\"status\", \"PROCESSING\"),\n * op.eq(\"status\", \"SHIPPED\")\n * ) // status = \"PENDING\" OR status = \"PROCESSING\" OR status = \"SHIPPED\"\n *\n * // High priority items\n * op.or(\n * op.eq(\"priority\", \"HIGH\"),\n * op.eq(\"urgent\", true)\n * )\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - OR}\n */\n or: (...conditions: Condition[]) => Condition;\n\n /**\n * Negates a condition with logical NOT operator.\n * Inverts the boolean result of the provided condition.\n *\n * @param condition - The condition to negate\n * @returns A condition that evaluates to true when the input condition is false\n *\n * @example\n * ```typescript\n * interface User { status: string; role: string; banned: boolean; }\n *\n * // Exclude specific status\n * op.not(op.eq(\"status\", \"DELETED\")) // NOT status = \"DELETED\"\n *\n * // Complex negation\n * op.not(\n * op.and(\n * op.eq(\"role\", \"guest\"),\n * op.eq(\"banned\", true)\n * )\n * ) // NOT (role = \"guest\" AND banned = true)\n *\n * // Exclude multiple values\n * op.not(op.inArray(\"status\", [\"DELETED\", \"ARCHIVED\"]))\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - NOT}\n */\n not: (condition: Condition) => Condition;\n};\n\n/**\n * Primary key type for QUERY operations.\n * Allows building complex key conditions for the sort key.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html AWS DynamoDB - Query Operations}\n *\n * @example\n * // Query items with a specific partition key and sort key prefix\n * table.query({\n * pk: \"USER#123\",\n * sk: op => op.beginsWith(\"ORDER#2023\")\n * })\n *\n * @example\n * // Query items within a specific sort key range\n * table.query({\n * pk: \"USER#123\",\n * sk: op => op.between(\"ORDER#2023-01\", \"ORDER#2023-12\")\n * })\n */\nexport type PrimaryKey = {\n /** Partition key value */\n pk: string;\n /** Optional sort key condition builder */\n sk?: (op: KeyConditionOperator) => Condition;\n};\n\n/**\n * Primary key type for GET and DELETE operations.\n * Used when you need to specify exact key values without conditions.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html AWS DynamoDB - Working with Items}\n *\n * @example\n * // Get a specific item by its complete primary key\n * table.get({\n * pk: \"USER#123\",\n * sk: \"PROFILE#123\"\n * })\n *\n * @example\n * // Delete a specific item by its complete primary key\n * table.delete({\n * pk: \"USER#123\",\n * sk: \"ORDER#456\"\n * })\n */\nexport type PrimaryKeyWithoutExpression = {\n /** Partition key value */\n pk: string;\n /** Optional sort key value */\n sk?: string;\n};\n","import type { DynamoItem, TableConfig } from \"../types\";\nimport type { PaginationResult, QueryBuilderInterface } from \"./builder-types\";\n\n/**\n * A utility class for handling DynamoDB pagination.\n * Use this class when you need to:\n * - Browse large collections of dinosaurs\n * - Review extensive security logs\n * - Analyze habitat inspection history\n * - Process feeding schedules\n *\n * The paginator maintains internal state and automatically handles:\n * - Page boundaries\n * - Result set limits\n * - Continuation tokens\n *\n * @example\n * ```typescript\n * // List all velociraptors with pagination\n * const paginator = new QueryBuilder(executor, eq('species', 'Velociraptor'))\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .paginate(10);\n *\n * // Process each page of dinosaurs\n * while (paginator.hasNextPage()) {\n * const page = await paginator.getNextPage();\n * console.log(`Processing page ${page.page} of velociraptors`);\n *\n * for (const raptor of page.items) {\n * console.log(`- ${raptor.id}: Health=${raptor.stats.health}`);\n * }\n * }\n * ```\n *\n * @typeParam T - The type of items being paginated\n * @typeParam TConfig - The table configuration type\n */\nexport class Paginator<T extends DynamoItem, TConfig extends TableConfig = TableConfig> {\n private queryBuilder: QueryBuilderInterface<T, TConfig>;\n private readonly pageSize?: number;\n private currentPage = 0;\n private lastEvaluatedKey?: DynamoItem;\n private hasMorePages = true;\n private totalItemsRetrieved = 0;\n private readonly overallLimit?: number;\n\n constructor(queryBuilder: QueryBuilderInterface<T, TConfig>, pageSize?: number) {\n this.queryBuilder = queryBuilder;\n this.pageSize = pageSize;\n // Store the overall limit from the query builder if it exists\n this.overallLimit = queryBuilder.getLimit();\n }\n\n /**\n * Gets the current page number (1-indexed).\n *\n * @example\n * ```ts\n * const paginator = new QueryBuilder(executor, eq('species', 'Tyrannosaurus'))\n * .paginate(5);\n *\n * await paginator.getNextPage();\n * console.log(`Reviewing T-Rex group ${paginator.getCurrentPage()}`);\n * ```\n *\n * @returns The current page number, starting from 1\n */\n public getCurrentPage(): number {\n return this.currentPage;\n }\n\n /**\n * Checks if there are more pages of dinosaurs or habitats to process.\n *\n * This method takes into account both:\n * - DynamoDB's lastEvaluatedKey mechanism\n * - Any overall limit set on the query\n *\n * @example\n * ```ts\n * // Process all security incidents\n * const paginator = new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))\n * .sortDescending()\n * .paginate(10);\n *\n * while (paginator.hasNextPage()) {\n * const page = await paginator.getNextPage();\n * for (const incident of page.items) {\n * await processSecurityBreach(incident);\n * }\n * console.log(`Processed incidents page ${page.page}`);\n * }\n * ```\n *\n * @returns true if there are more pages available, false otherwise\n */\n public hasNextPage(): boolean {\n // If we have an overall limit and we've already retrieved that many items, there are no more pages\n if (this.overallLimit !== undefined && this.totalItemsRetrieved >= this.overallLimit) {\n return false;\n }\n return this.hasMorePages;\n }\n\n /**\n * Retrieves the next page of dinosaurs or habitats from DynamoDB.\n *\n * This method handles:\n * - Automatic continuation between groups\n * - Respect for park capacity limits\n * - Group size adjustments for safety\n *\n * @example\n * ```ts\n * const paginator = new QueryBuilder(executor, eq('species', 'Velociraptor'))\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .paginate(5);\n *\n * // Check first raptor group\n * const page1 = await paginator.getNextPage();\n * console.log(`Found ${page1.items.length} active raptors`);\n *\n * // Continue inspection if more groups exist\n * if (page1.hasNextPage) {\n * const page2 = await paginator.getNextPage();\n * console.log(`Inspecting raptor group ${page2.page}`);\n *\n * for (const raptor of page2.items) {\n * await performHealthCheck(raptor);\n * }\n * }\n * ```\n *\n * @returns A promise that resolves to a PaginationResult containing:\n * - items: The dinosaurs/habitats for this page\n * - hasNextPage: Whether more groups exist\n * - page: The current group number\n * - lastEvaluatedKey: DynamoDB's continuation token\n */\n public async getNextPage(): Promise<PaginationResult<T>> {\n if (!this.hasNextPage()) {\n return {\n items: [],\n hasNextPage: false,\n page: this.currentPage,\n };\n }\n\n // Calculate how many items to fetch for this page\n let effectivePageSize = this.pageSize;\n\n // If we have an overall limit, make sure we don't fetch more than what's left\n if (this.overallLimit !== undefined) {\n const remainingItems = this.overallLimit - this.totalItemsRetrieved;\n if (remainingItems <= 0) {\n return {\n items: [],\n hasNextPage: false,\n page: this.currentPage,\n };\n }\n if (effectivePageSize !== undefined) {\n effectivePageSize = Math.min(effectivePageSize, remainingItems);\n } else {\n effectivePageSize = remainingItems;\n }\n }\n\n // Clone the query builder to avoid modifying the original\n const query = this.queryBuilder.clone();\n\n // Only set limit if we have an effective page size (not automatic paging)\n if (effectivePageSize !== undefined) {\n query.limit(effectivePageSize);\n }\n\n // Apply the last evaluated key if we have one\n if (this.lastEvaluatedKey) {\n query.startFrom(this.lastEvaluatedKey);\n }\n\n // Execute the query and get the first page from the generator\n const generator = await query.execute();\n const items: T[] = [];\n\n // Take items up to the effective page size\n let itemCount = 0;\n for await (const item of generator) {\n if (effectivePageSize !== undefined && itemCount >= effectivePageSize) {\n break;\n }\n items.push(item);\n itemCount++;\n }\n\n // Get the last evaluated key from the generator\n const lastEvaluatedKey = generator.getLastEvaluatedKey();\n\n const result = { items, lastEvaluatedKey };\n\n // Update pagination state\n this.currentPage += 1;\n this.lastEvaluatedKey = result.lastEvaluatedKey;\n this.totalItemsRetrieved += result.items.length;\n\n // Determine if there are more pages\n // We have more pages if:\n // 1. DynamoDB returned a lastEvaluatedKey AND\n // 2. We haven't hit our overall limit (if one exists)\n this.hasMorePages =\n !!result.lastEvaluatedKey && (this.overallLimit === undefined || this.totalItemsRetrieved < this.overallLimit);\n\n return {\n items: result.items,\n lastEvaluatedKey: result.lastEvaluatedKey,\n hasNextPage: this.hasNextPage(),\n page: this.currentPage,\n };\n }\n\n /**\n * Gets all remaining dinosaurs or habitats and combines them into a single array.\n *\n * @example\n * ```ts\n * // Get complete carnivore inventory\n * const paginator = new QueryBuilder(executor, eq('diet', 'CARNIVORE'))\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .paginate(10);\n *\n * try {\n * const allCarnivores = await paginator.getAllPages();\n * console.log(`Park contains ${allCarnivores.length} active carnivores`);\n *\n * // Calculate total threat level\n * const totalThreat = allCarnivores.reduce(\n * (sum, dino) => sum + dino.stats.threatLevel,\n * 0\n * );\n * console.log(`Total threat level: ${totalThreat}`);\n * } catch (error) {\n * console.error('Failed to complete carnivore census:', error);\n * }\n * ```\n *\n * @returns A promise that resolves to an array containing all remaining items\n */\n public async getAllPages(): Promise<T[]> {\n const allItems: T[] = [];\n\n while (this.hasNextPage()) {\n const result = await this.getNextPage();\n allItems.push(...result.items);\n }\n\n return allItems;\n }\n}\n","import {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n between,\n inArray,\n beginsWith,\n contains,\n attributeExists,\n attributeNotExists,\n and,\n or,\n not,\n type Condition,\n type ConditionOperator,\n} from \"../conditions\";\nimport { Paginator } from \"./paginator\";\nimport type { DynamoItem, GSINames, TableConfig } from \"../types\";\nimport type { FilterBuilderInterface } from \"./builder-types\";\nimport type { ResultIterator } from \"./result-iterator\";\n\n/**\n * Configuration options for DynamoDB filter operations.\n * These are common options shared between query and scan operations.\n */\nexport interface FilterOptions {\n /** Filter conditions applied to results */\n filter?: Condition;\n /** Maximum number of items to return */\n limit?: number;\n /** Name of the Global Secondary Index to use */\n indexName?: string;\n /** Whether to use strongly consistent reads */\n consistentRead?: boolean;\n /** List of attributes to return in the result */\n projection?: string[];\n /** Token for starting the operation from a specific point */\n lastEvaluatedKey?: DynamoItem;\n}\n\n/**\n * Abstract base builder for creating DynamoDB filter operations.\n * This class provides common functionality for both Query and Scan operations.\n *\n * The builder supports:\n * - Type-safe GSI selection\n * - Complex filter conditions\n * - Pagination\n * - Consistent reads\n * - Attribute projection\n *\n * @typeParam T - The type of items being filtered\n * @typeParam TConfig - The table configuration type for type-safe GSI selection\n */\nexport abstract class FilterBuilder<T extends DynamoItem, TConfig extends TableConfig = TableConfig>\n implements FilterBuilderInterface<T, TConfig>\n{\n protected options: FilterOptions = {};\n protected selectedFields: Set<string> = new Set();\n\n /**\n * Sets the maximum number of items to return.\n *\n * Note: This limit applies to the items that match the key condition\n * before any filter expressions are applied.\n *\n * @example\n * ```typescript\n * // Get first 10 dinosaurs\n * const result = await builder\n * .limit(10)\n * .execute();\n * ```\n *\n * @param limit - Maximum number of items to return\n * @returns The builder instance for method chaining\n */\n limit(limit: number): this {\n this.options.limit = limit;\n return this;\n }\n\n /**\n * Gets the current limit set on the operation.\n * This is used internally by the paginator to manage result sets.\n *\n * @returns The current limit or undefined if no limit is set\n */\n getLimit(): number | undefined {\n return this.options.limit;\n }\n\n /**\n * Specifies a Global Secondary Index (GSI) to use for the operation.\n *\n * @example\n * ```typescript\n * // Find all dinosaurs of a specific species\n * builder\n * .useIndex('species-status-index')\n * .filter(op => op.eq('status', 'ACTIVE'));\n *\n * // Search high-security habitats\n * builder\n * .useIndex('security-level-index')\n * .filter(op =>\n * op.and([\n * op.gt('securityLevel', 8),\n * op.eq('status', 'OPERATIONAL')\n * ])\n * );\n * ```\n *\n * @param indexName - The name of the GSI to use (type-safe based on table configuration)\n * @returns The builder instance for method chaining\n */\n useIndex<I extends GSINames<TConfig>>(indexName: I): this {\n this.options.indexName = indexName as string;\n return this;\n }\n\n /**\n * Sets whether to use strongly consistent reads for the operation.\n *\n * Note:\n * - Consistent reads are not available on GSIs\n * - Consistent reads consume twice the throughput\n * - Default is eventually consistent reads\n *\n * @example\n * ```typescript\n * // Check immediate dinosaur status\n * const result = await builder\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .consistentRead()\n * .execute();\n *\n * // Monitor security breaches\n * const result = await builder\n * .useIndex('primary-index')\n * .consistentRead(isEmergencyMode)\n * .execute();\n * ```\n *\n * @param consistentRead - Whether to use consistent reads (defaults to true)\n * @returns The builder instance for method chaining\n */\n consistentRead(consistentRead = true): this {\n this.options.consistentRead = consistentRead;\n return this;\n }\n\n /**\n * Adds a filter expression to refine the operation results.\n *\n * @example\n * ```typescript\n * // Find aggressive carnivores\n * builder.filter(op =>\n * op.and([\n * op.eq('diet', 'CARNIVORE'),\n * op.gt('aggressionLevel', 7),\n * op.eq('status', 'ACTIVE')\n * ])\n * );\n *\n * // Search suitable breeding habitats\n * builder.filter(op =>\n * op.and([\n * op.between('temperature', 25, 30),\n * op.lt('currentOccupants', 3),\n * op.eq('quarantineStatus', 'CLEAR')\n * ])\n * );\n * ```\n *\n * @param condition - Either a Condition object or a callback function that builds the condition\n * @returns The builder instance for method chaining\n */\n filter(condition: Condition | ((op: ConditionOperator<T>) => Condition)): this {\n if (typeof condition === \"function\") {\n const conditionOperator: ConditionOperator<T> = {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n between,\n inArray,\n beginsWith,\n contains,\n attributeExists,\n attributeNotExists,\n and,\n or,\n not,\n };\n this.options.filter = condition(conditionOperator);\n } else {\n this.options.filter = condition;\n }\n return this;\n }\n\n /**\n * Specifies which attributes to return in the results.\n *\n * @example\n * ```typescript\n * // Get basic dinosaur info\n * builder.select([\n * 'species',\n * 'status',\n * 'stats.health',\n * 'stats.aggressionLevel'\n * ]);\n *\n * // Monitor habitat conditions\n * builder\n * .select('securityStatus')\n * .select([\n * 'currentOccupants',\n * 'temperature',\n * 'lastInspectionDate'\n * ]);\n * ```\n *\n * @param fields - A single field name or an array of field names to return\n * @returns The builder instance for method chaining\n */\n select(fields: string | string[]): this {\n if (typeof fields === \"string\") {\n this.selectedFields.add(fields);\n } else if (Array.isArray(fields)) {\n for (const field of fields) {\n this.selectedFields.add(field);\n }\n }\n\n this.options.projection = Array.from(this.selectedFields);\n return this;\n }\n\n /**\n * Creates a paginator that handles DynamoDB pagination automatically.\n * The paginator handles:\n * - Tracking the last evaluated key\n * - Managing page boundaries\n * - Respecting overall query limits\n *\n * @example\n * ```typescript\n * // Create a paginator for dinosaur records with specific page size\n * const paginator = builder\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .paginate(10);\n *\n * // Create a paginator with automatic DynamoDB paging (no page size limit)\n * const autoPaginator = builder\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .paginate();\n *\n * // Process pages of dinosaur results\n * while (paginator.hasNextPage()) {\n * const page = await paginator.getNextPage();\n * console.log(`Processing page ${page.page}, count: ${page.items.length}`);\n * // Process dinosaur data\n * }\n * ```\n *\n * @param pageSize - The number of items to return per page. If not provided, DynamoDB will automatically determine page sizes.\n * @returns A Paginator instance that manages the pagination state\n * @see Paginator for more pagination control options\n */\n paginate(pageSize?: number): Paginator<T, TConfig> {\n return new Paginator<T, TConfig>(this, pageSize);\n }\n\n /**\n * Sets the starting point using a previous lastEvaluatedKey.\n *\n * Note: This method is typically used for manual pagination.\n * For automatic pagination, use the paginate() method instead.\n *\n * @example\n * ```typescript\n * // First batch of dinosaurs\n * const result1 = await builder\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .limit(5)\n * .execute();\n *\n * const lastKey = result1.getLastEvaluatedKey();\n * if (lastKey) {\n * // Continue listing dinosaurs\n * const result2 = await builder\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .startFrom(lastKey)\n * .limit(5)\n * .execute();\n *\n * const items = await result2.toArray();\n * console.log('Additional dinosaurs:', items);\n * }\n * ```\n *\n * @param lastEvaluatedKey - The exclusive start key from a previous result\n * @returns The builder instance for method chaining\n */\n startFrom(lastEvaluatedKey: DynamoItem): this {\n this.options.lastEvaluatedKey = lastEvaluatedKey;\n return this;\n }\n\n /**\n * Creates a deep clone of this builder instance.\n *\n * This is particularly useful when:\n * - Implementing pagination (used internally by paginate())\n * - Creating operation templates\n * - Running multiple variations of an operation\n *\n * @example\n * ```typescript\n * // Create base dinosaur query\n * const baseBuilder = builder\n * .useIndex('status-index')\n * .select(['id', 'status', 'location']);\n *\n * // Check active dinosaurs\n * const activeRaptors = baseBuilder.clone()\n * .filter(op => op.eq('status', 'HUNTING'))\n * .execute();\n *\n * // Check contained dinosaurs\n * const containedRaptors = baseBuilder.clone()\n * .filter(op => op.eq('status', 'CONTAINED'))\n * .execute();\n * ```\n *\n * @returns A new builder instance with the same configuration\n */\n abstract clone(): FilterBuilderInterface<T, TConfig>;\n\n /**\n * Executes the operation against DynamoDB and returns a generator that behaves like an array.\n * This method must be implemented by subclasses to handle\n * their specific execution logic.\n */\n abstract execute(): Promise<ResultIterator<T, TConfig>>;\n}\n","import type { DynamoItem, TableConfig } from \"../types\";\nimport type { QueryBuilderInterface } from \"./builder-types\";\n\n/**\n * Function type for executing DynamoDB operations and returning raw results.\n */\ntype DirectExecutor<T extends DynamoItem> = () => Promise<{ items: T[]; lastEvaluatedKey?: DynamoItem }>;\n\n/**\n * Minimal result generator that provides async iteration over DynamoDB results with automatic pagination.\n *\n * @example\n * ```typescript\n * const results = await queryBuilder.execute();\n *\n * for await (const item of results) {\n * console.log(item);\n * }\n * ```\n */\nexport class ResultIterator<T extends DynamoItem, TConfig extends TableConfig = TableConfig> {\n private lastEvaluatedKey?: DynamoItem | null;\n private itemsYielded = 0;\n private readonly overallLimit?: number;\n\n constructor(\n private queryBuilder: QueryBuilderInterface<T, TConfig>,\n private directExecutor: DirectExecutor<T>,\n ) {\n this.overallLimit = queryBuilder.getLimit();\n }\n\n /**\n * Async iterator with automatic pagination\n */\n async *[Symbol.asyncIterator](): AsyncIterableIterator<T> {\n let hasMorePages = true;\n\n while (hasMorePages) {\n const result = await this.directExecutor();\n\n for (const item of result.items) {\n // Check if we've reached the overall limit\n if (this.overallLimit !== undefined && this.itemsYielded >= this.overallLimit) {\n return;\n }\n \n yield item;\n this.itemsYielded++;\n }\n\n // Update lastEvaluatedKey, but preserve the last non-null value\n if (result.lastEvaluatedKey !== null && result.lastEvaluatedKey !== undefined) {\n this.lastEvaluatedKey = result.lastEvaluatedKey;\n // Update the query builder's options for the next iteration\n this.queryBuilder.startFrom(result.lastEvaluatedKey);\n } else if (result.lastEvaluatedKey === null) {\n // Only set to null if we haven't seen a lastEvaluatedKey yet\n if (this.lastEvaluatedKey === undefined) {\n this.lastEvaluatedKey = null;\n }\n }\n \n // Stop if we've reached the overall limit or no more pages\n hasMorePages = !!result.lastEvaluatedKey && \n (this.overallLimit === undefined || this.itemsYielded < this.overallLimit);\n }\n }\n\n /**\n * Convert to array (loads all pages).\n *\n * ```ts\n * const result = await table.query({ pk: \"foo\" }).execute();\n * const allItemsFromDynamo = await result.toArray();\n * ```\n *\n * Note: This will load all pages into memory. For large datasets, consider using async iteration instead.\n *```ts\n * const result = await table.query({ pk: \"foo\" }).execute();\n * for await (const item of result) {\n * // Process each item\n * }\n * ```\n */\n async toArray(): Promise<T[]> {\n const items: T[] = [];\n for await (const item of this) {\n items.push(item);\n }\n return items;\n }\n\n /**\n * Get the last evaluated key\n */\n getLastEvaluatedKey(): DynamoItem | undefined {\n return this.lastEvaluatedKey === null ? undefined : this.lastEvaluatedKey;\n }\n}\n","import type { Condition } from \"../conditions\";\nimport { FilterBuilder, type FilterOptions } from \"./filter-builder\";\nimport type { DynamoItem, TableConfig } from \"../types\";\nimport type { QueryBuilderInterface } from \"./builder-types\";\nimport { ResultIterator } from \"./result-iterator\";\n\n/**\n * Configuration options for DynamoDB query operations.\n * Extends the base FilterOptions with query-specific options.\n */\nexport interface QueryOptions extends FilterOptions {\n /** Condition for the sort key in the table or index */\n sortKeyCondition?: Condition;\n /** Direction of sort key traversal (true for ascending, false for descending) */\n scanIndexForward?: boolean;\n}\n\n/**\n * Function type for executing DynamoDB query operations.\n * @typeParam T - The type of items being queried\n */\ntype QueryExecutor<T extends DynamoItem> = (\n keyCondition: Condition,\n options: QueryOptions,\n) => Promise<{ items: T[]; lastEvaluatedKey?: Record<string, unknown> }>;\n\n/**\n * Builder for creating DynamoDB query operations.\n *\n * The builder supports:\n * - Type-safe GSI selection\n * - Complex filter conditions\n * - Automatic pagination handling\n * - Consistent reads\n * - Forward and reverse sorting\n *\n * @example\n * ```typescript\n * // Simple query\n * const result = await new QueryBuilder(executor, eq('userId', '123'))\n * .execute();\n *\n * // Complex query with GSI and filtering\n * const result = await new QueryBuilder(executor, eq('status', 'ACTIVE'))\n * .useIndex('status-index')\n * .filter(op => op.beginsWith('name', 'John'))\n * .select(['id', 'name', 'email'])\n * .sortDescending()\n * .limit(10)\n * .execute();\n *\n * // Query with pagination\n * const paginator = new QueryBuilder(executor, eq('type', 'order'))\n * .paginate(25);\n *\n * while (paginator.hasNextPage()) {\n * const page = await paginator.getNextPage();\n * // Process page.items\n * }\n * ```\n *\n * @typeParam T - The type of items being queried\n * @typeParam TConfig - The table configuration type for type-safe GSI selection\n */\nexport class QueryBuilder<T extends DynamoItem, TConfig extends TableConfig = TableConfig>\n extends FilterBuilder<T, TConfig>\n implements QueryBuilderInterface<T, TConfig>\n{\n private readonly keyCondition: Condition;\n protected override options: QueryOptions = {};\n protected readonly executor: QueryExecutor<T>;\n\n constructor(executor: QueryExecutor<T>, keyCondition: Condition) {\n super();\n this.executor = executor;\n this.keyCondition = keyCondition;\n }\n\n /**\n * Sets the maximum number of items to return from the query.\n *\n * Note: This is the default behavior if no sort order is specified.\n *\n * @example\n * ```typescript\n * // Get orders in chronological order\n * const result = await new QueryBuilder(executor, eq('userId', '123'))\n * .sortAscending()\n * .execute();\n *\n * // Get events from oldest to newest\n * const result = await new QueryBuilder(executor, eq('entityId', 'order-123'))\n * .useIndex('entity-timestamp-index')\n * .sortAscending()\n * .execute();\n * ```\n *\n * @returns The builder instance for method chaining\n */\n /**\n * Sets the query to return items in ascending order by sort key.\n *\n * @example\n * ```typescript\n * // List dinosaurs by age\n * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))\n * .useIndex('age-index')\n * .sortAscending()\n * .execute();\n *\n * // View incidents chronologically\n * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))\n * .useIndex('date-index')\n * .sortAscending()\n * .execute();\n * ```\n *\n * @returns The builder instance for method chaining\n */\n sortAscending(): this {\n this.options.scanIndexForward = true;\n return this;\n }\n\n /**\n * Sets the query to return items in descending order by sort key.\n *\n * @example\n * ```typescript\n * // Get most recent security incidents\n * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))\n * .useIndex('date-index')\n * .sortDescending()\n * .limit(10)\n * .execute();\n *\n * // Check latest dinosaur activities\n * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))\n * .useIndex('activity-time-index')\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .sortDescending()\n * .execute();\n * ```\n *\n * @returns The builder instance for method chaining\n */\n sortDescending(): this {\n this.options.scanIndexForward = false;\n return this;\n }\n\n /**\n * Creates a deep clone of this QueryBuilder instance.\n *\n * This is particularly useful when:\n * - Implementing pagination (used internally by paginate())\n * - Creating query templates\n * - Running multiple variations of a query\n *\n * @example\n * ```typescript\n * // Create base dinosaur query\n * const baseQuery = new QueryBuilder(executor, eq('species', 'Velociraptor'))\n * .useIndex('status-index')\n * .select(['id', 'status', 'location']);\n *\n * // Check active dinosaurs\n * const activeRaptors = baseQuery.clone()\n * .filter(op => op.eq('status', 'HUNTING'))\n * .execute();\n *\n * // Check contained dinosaurs\n * const containedRaptors = baseQuery.clone()\n * .filter(op => op.eq('status', 'CONTAINED'))\n * .execute();\n *\n * // Check sedated dinosaurs\n * const sedatedRaptors = baseQuery.clone()\n * .filter(op => op.eq('status', 'SEDATED'))\n * .execute();\n * ```\n *\n * @returns A new QueryBuilder instance with the same configuration\n */\n clone(): QueryBuilder<T, TConfig> {\n const clone = new QueryBuilder<T, TConfig>(this.executor, this.keyCondition);\n clone.options = { ...this.options };\n clone.selectedFields = new Set(this.selectedFields);\n return clone;\n }\n\n /**\n * Executes the query against DynamoDB and returns a generator that behaves like an array.\n *\n * The generator automatically handles pagination and provides array-like methods\n * for processing results efficiently without loading everything into memory at once.\n *\n * @example\n * ```typescript\n * try {\n * // Find active carnivores with automatic pagination\n * const results = await new QueryBuilder(executor, eq('habitatId', 'PADDOCK-A'))\n * .useIndex('species-status-index')\n * .filter(op =>\n * op.and([\n * op.eq('diet', 'CARNIVORE'),\n * op.eq('status', 'ACTIVE'),\n * op.gt('aggressionLevel', 7)\n * ])\n * )\n * .sortDescending()\n * .execute();\n *\n * // Use like an array with automatic pagination\n * for await (const dinosaur of results) {\n * console.log(`Processing ${dinosaur.name}`);\n * }\n *\n * // Or convert to array and use array methods\n * const allItems = await results.toArray();\n * const dangerousOnes = allItems.filter(dino => dino.aggressionLevel > 9);\n * const totalCount = allItems.length;\n * } catch (error) {\n * console.error('Security scan failed:', error);\n * }\n * ```\n *\n * @returns A promise that resolves to a ResultGenerator that behaves like an array\n */\n async execute(): Promise<ResultIterator<T, TConfig>> {\n const directExecutor = () => this.executor(this.keyCondition, this.options);\n return new ResultIterator(this, directExecutor);\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/conditions.ts","../../src/builders/paginator.ts","../../src/builders/filter-builder.ts","../../src/builders/result-iterator.ts","../../src/builders/query-builder.ts"],"names":[],"mappings":"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","file":"query-builder.cjs","sourcesContent":["import type { Path, PathType } from \"./builders/types\";\nimport type { DynamoItem } from \"./types\";\n\n/**\n * Supported comparison operators for DynamoDB conditions.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html AWS DynamoDB - Comparison Operator Reference}\n *\n * - eq: Equals (=)\n * - ne: Not equals (≠ / <>)\n * - lt: Less than (<)\n * - lte: Less than or equal to (≤)\n * - gt: Greater than (>)\n * - gte: Greater than or equal to (≥)\n * - between: Between two values (inclusive)\n * - in: Checks if attribute value is in a list of values\n * - beginsWith: Checks if string attribute begins with specified substring\n * - contains: Checks if string/set attribute contains specified value\n * - attributeExists: Checks if attribute exists\n * - attributeNotExists: Checks if attribute does not exist\n */\nexport type ComparisonOperator =\n | \"eq\"\n | \"ne\"\n | \"lt\"\n | \"lte\"\n | \"gt\"\n | \"gte\"\n | \"between\"\n | \"in\"\n | \"beginsWith\"\n | \"contains\"\n | \"attributeExists\"\n | \"attributeNotExists\";\n\n/**\n * Logical operators for combining multiple conditions.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - Logical Operator Reference}\n *\n * - and: Evaluates to true if all conditions are true\n * - or: Evaluates to true if any condition is true\n * - not: Negate the result of a condition\n */\nexport type LogicalOperator = \"and\" | \"or\" | \"not\";\n\n/**\n * Represents a DynamoDB condition expression.\n * Can be either a comparison condition or a logical combination of conditions.\n *\n * @example\n * // Simple comparison condition\n * const condition: Condition = {\n * type: \"eq\",\n * attr: \"status\",\n * value: \"ACTIVE\"\n * };\n *\n * @example\n * // Logical combination of conditions\n * const condition: Condition = {\n * type: \"and\",\n * conditions: [\n * { type: \"eq\", attr: \"status\", value: \"ACTIVE\" },\n * { type: \"gt\", attr: \"age\", value: 5 }\n * ]\n * };\n */\nexport interface Condition {\n /** The type of condition (comparison or logical operator) */\n type: ComparisonOperator | LogicalOperator;\n /** The attribute name for comparison conditions */\n attr?: string;\n /** The value to compare against for comparison conditions */\n value?: unknown;\n /** Array of conditions for logical operators (and/or) */\n conditions?: Condition[];\n /** Single condition for the 'not' operator */\n condition?: Condition;\n}\n\n/**\n * Parameters used to build DynamoDB expression strings.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeNames.html Expression Attribute Names}\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeValues.html Expression Attribute Values}\n */\nexport interface ExpressionParams {\n /** Map of attribute name placeholders to actual attribute names */\n expressionAttributeNames: Record<string, string>;\n /** Map of value placeholders to actual values */\n expressionAttributeValues: DynamoItem;\n /** Counter for generating unique value placeholders */\n valueCounter: { count: number };\n}\n\n/**\n * Creates a comparison condition builder function for the specified operator.\n * @internal\n */\nexport const createComparisonCondition =\n (type: ComparisonOperator) =>\n (attr: string, value: unknown): Condition => ({\n type,\n attr,\n value,\n });\n\n/**\n * Creates an equals (=) condition\n * @example\n * eq(\"status\", \"ACTIVE\") // status = \"ACTIVE\"\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html}\n */\nexport const eq = createComparisonCondition(\"eq\");\n\n/**\n * Creates a not equals (≠) condition\n * @example\n * ne(\"status\", \"DELETED\") // status <> \"DELETED\"\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html}\n */\nexport const ne = createComparisonCondition(\"ne\");\n\n/**\n * Creates a less than (<) condition\n * @example\n * lt(\"age\", 18) // age < 18\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html}\n */\nexport const lt = createComparisonCondition(\"lt\");\n\n/**\n * Creates a less than or equal to (≤) condition\n * @example\n * lte(\"age\", 18) // age <= 18\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html}\n */\nexport const lte = createComparisonCondition(\"lte\");\n\n/**\n * Creates a greater than (>) condition\n * @example\n * gt(\"price\", 100) // price > 100\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html}\n */\nexport const gt = createComparisonCondition(\"gt\");\n\n/**\n * Creates a greater than or equal to (≥) condition\n * @example\n * gte(\"price\", 100) // price >= 100\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html}\n */\nexport const gte = createComparisonCondition(\"gte\");\n\n/**\n * Creates a between condition that checks if a value is within a range (inclusive)\n * @example\n * between(\"age\", 18, 65) // age BETWEEN 18 AND 65\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - BETWEEN}\n */\nexport const between = (attr: string, lower: unknown, upper: unknown): Condition => ({\n type: \"between\",\n attr,\n value: [lower, upper],\n});\n\n/**\n * Creates an in condition that checks if a value is in a list of values\n * @example\n * inArray(\"status\", [\"ACTIVE\", \"PENDING\", \"PROCESSING\"]) // status IN (\"ACTIVE\", \"PENDING\", \"PROCESSING\")\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - IN}\n */\nexport const inArray = (attr: string, values: unknown[]): Condition => ({\n type: \"in\",\n attr,\n value: values,\n});\n\n/**\n * Creates a begins_with condition that checks if a string attribute starts with a substring\n * @example\n * beginsWith(\"email\", \"@example.com\") // begins_with(email, \"@example.com\")\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - begins_with}\n */\nexport const beginsWith = createComparisonCondition(\"beginsWith\");\n\n/**\n * Creates a contains condition that checks if a string contains a substring or if a set contains an element\n * @example\n * contains(\"tags\", \"important\") // contains(tags, \"important\")\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - contains}\n */\nexport const contains = createComparisonCondition(\"contains\");\n\n/**\n * Creates a condition that checks if an attribute exists\n * @example\n * attributeExists(\"email\") // attribute_exists(email)\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - attribute_exists}\n */\nexport const attributeExists = (attr: string): Condition => ({\n type: \"attributeExists\",\n attr,\n});\n\n/**\n * Creates a condition that checks if an attribute does not exist\n * @example\n * attributeNotExists(\"deletedAt\") // attribute_not_exists(deletedAt)\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - attribute_not_exists}\n */\nexport const attributeNotExists = (attr: string): Condition => ({\n type: \"attributeNotExists\",\n attr,\n});\n\n// --- Logical Operators ---\n\n/**\n * Combines multiple conditions with AND operator\n * @example\n * and(\n * eq(\"status\", \"ACTIVE\"),\n * gt(\"age\", 18)\n * ) // status = \"ACTIVE\" AND age > 18\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - AND}\n */\nexport const and = (...conditions: Condition[]): Condition => ({\n type: \"and\",\n conditions,\n});\n\n/**\n * Combines multiple conditions with OR operator\n * @example\n * or(\n * eq(\"status\", \"PENDING\"),\n * eq(\"status\", \"PROCESSING\")\n * ) // status = \"PENDING\" OR status = \"PROCESSING\"\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - OR}\n */\nexport const or = (...conditions: Condition[]): Condition => ({\n type: \"or\",\n conditions,\n});\n\n/**\n * Negates a condition\n * @example\n * not(eq(\"status\", \"DELETED\")) // NOT status = \"DELETED\"\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - NOT}\n */\nexport const not = (condition: Condition): Condition => ({\n type: \"not\",\n condition,\n});\n\n/**\n * Type-safe operators for building key conditions in DynamoDB queries.\n * Only includes operators that are valid for key conditions.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.KeyConditionExpressions AWS DynamoDB - Key Condition Expressions}\n *\n * @example\n * // Using with sort key conditions\n * table.query({\n * pk: \"USER#123\",\n * sk: op => op.beginsWith(\"ORDER#\")\n * })\n */\nexport type KeyConditionOperator = {\n /** Equals comparison for key attributes */\n eq: (value: unknown) => Condition;\n /** Less than comparison for key attributes */\n lt: (value: unknown) => Condition;\n /** Less than or equal comparison for key attributes */\n lte: (value: unknown) => Condition;\n /** Greater than comparison for key attributes */\n gt: (value: unknown) => Condition;\n /** Greater than or equal comparison for key attributes */\n gte: (value: unknown) => Condition;\n /** Between range comparison for key attributes */\n between: (lower: unknown, upper: unknown) => Condition;\n /** Begins with comparison for key attributes */\n beginsWith: (value: unknown) => Condition;\n /** Combines multiple key conditions with AND */\n and: (...conditions: Condition[]) => Condition;\n};\n\n/**\n * Type-safe operators for building conditions in DynamoDB operations.\n * Includes all available condition operators with proper type inference.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html AWS DynamoDB - Condition Expressions}\n *\n * @example\n * // Using with type-safe conditions\n * interface User {\n * status: string;\n * age: number;\n * email?: string;\n * }\n *\n * table.scan<User>()\n * .where(op => op.and(\n * op.eq(\"status\", \"ACTIVE\"),\n * op.gt(\"age\", 18),\n * op.attributeExists(\"email\")\n * ))\n *\n * @template T The type of the item being operated on\n */\nexport type ConditionOperator<T extends DynamoItem> = {\n /**\n * Creates an equals (=) condition for type-safe attribute comparison.\n * Tests if the specified attribute equals the provided value.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param value - The value to compare against (must match attribute type)\n * @returns A condition that evaluates to true when attr equals value\n *\n * @example\n * ```typescript\n * interface User { status: string; age: number; }\n *\n * // String comparison\n * op.eq(\"status\", \"ACTIVE\") // status = \"ACTIVE\"\n *\n * // Numeric comparison\n * op.eq(\"age\", 25) // age = 25\n *\n * // Nested attribute\n * op.eq(\"profile.role\", \"admin\") // profile.role = \"admin\"\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - Comparison Operators}\n */\n eq: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a not equals (≠ / <>) condition for type-safe attribute comparison.\n * Tests if the specified attribute does not equal the provided value.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param value - The value to compare against (must match attribute type)\n * @returns A condition that evaluates to true when attr does not equal value\n *\n * @example\n * ```typescript\n * interface User { status: string; priority: number; }\n *\n * // String comparison\n * op.ne(\"status\", \"DELETED\") // status <> \"DELETED\"\n *\n * // Numeric comparison\n * op.ne(\"priority\", 0) // priority <> 0\n *\n * // Useful for filtering out specific values\n * op.ne(\"category\", \"ARCHIVED\") // category <> \"ARCHIVED\"\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - Comparison Operators}\n */\n ne: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a less than (<) condition for type-safe attribute comparison.\n * Tests if the specified attribute is less than the provided value.\n * Works with numbers, strings (lexicographic), and dates.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param value - The value to compare against (must match attribute type)\n * @returns A condition that evaluates to true when attr is less than value\n *\n * @example\n * ```typescript\n * interface Product { price: number; name: string; createdAt: string; }\n *\n * // Numeric comparison\n * op.lt(\"price\", 100) // price < 100\n *\n * // String comparison (lexicographic)\n * op.lt(\"name\", \"M\") // name < \"M\" (names starting with A-L)\n *\n * // Date comparison (ISO strings)\n * op.lt(\"createdAt\", \"2024-01-01\") // createdAt < \"2024-01-01\"\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - Comparison Operators}\n */\n lt: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a less than or equal to (≤) condition for type-safe attribute comparison.\n * Tests if the specified attribute is less than or equal to the provided value.\n * Works with numbers, strings (lexicographic), and dates.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param value - The value to compare against (must match attribute type)\n * @returns A condition that evaluates to true when attr is less than or equal to value\n *\n * @example\n * ```typescript\n * interface Order { total: number; priority: number; dueDate: string; }\n *\n * // Numeric comparison\n * op.lte(\"total\", 1000) // total <= 1000\n *\n * // Priority levels\n * op.lte(\"priority\", 3) // priority <= 3 (low to medium priority)\n *\n * // Date deadlines\n * op.lte(\"dueDate\", \"2024-12-31\") // dueDate <= \"2024-12-31\"\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - Comparison Operators}\n */\n lte: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a greater than (>) condition for type-safe attribute comparison.\n * Tests if the specified attribute is greater than the provided value.\n * Works with numbers, strings (lexicographic), and dates.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param value - The value to compare against (must match attribute type)\n * @returns A condition that evaluates to true when attr is greater than value\n *\n * @example\n * ```typescript\n * interface User { age: number; score: number; lastLogin: string; }\n *\n * // Age restrictions\n * op.gt(\"age\", 18) // age > 18 (adults only)\n *\n * // Performance thresholds\n * op.gt(\"score\", 85) // score > 85 (high performers)\n *\n * // Recent activity\n * op.gt(\"lastLogin\", \"2024-01-01\") // lastLogin > \"2024-01-01\"\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - Comparison Operators}\n */\n gt: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a greater than or equal to (≥) condition for type-safe attribute comparison.\n * Tests if the specified attribute is greater than or equal to the provided value.\n * Works with numbers, strings (lexicographic), and dates.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param value - The value to compare against (must match attribute type)\n * @returns A condition that evaluates to true when attr is greater than or equal to value\n *\n * @example\n * ```typescript\n * interface Product { rating: number; version: string; releaseDate: string; }\n *\n * // Minimum ratings\n * op.gte(\"rating\", 4.0) // rating >= 4.0 (highly rated)\n *\n * // Version requirements\n * op.gte(\"version\", \"2.0.0\") // version >= \"2.0.0\"\n *\n * // Release date filters\n * op.gte(\"releaseDate\", \"2024-01-01\") // releaseDate >= \"2024-01-01\"\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - Comparison Operators}\n */\n gte: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a between condition for type-safe range comparison.\n * Tests if the specified attribute value falls within the inclusive range [lower, upper].\n * Works with numbers, strings (lexicographic), and dates.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param lower - The lower bound of the range (inclusive, must match attribute type)\n * @param upper - The upper bound of the range (inclusive, must match attribute type)\n * @returns A condition that evaluates to true when lower ≤ attr ≤ upper\n *\n * @example\n * ```typescript\n * interface Event { price: number; date: string; priority: number; }\n *\n * // Price range\n * op.between(\"price\", 50, 200) // price BETWEEN 50 AND 200\n *\n * // Date range\n * op.between(\"date\", \"2024-01-01\", \"2024-12-31\") // date BETWEEN \"2024-01-01\" AND \"2024-12-31\"\n *\n * // Priority levels\n * op.between(\"priority\", 1, 5) // priority BETWEEN 1 AND 5\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - BETWEEN}\n */\n between: <K extends Path<T>>(attr: K, lower: PathType<T, K>, upper: PathType<T, K>) => Condition;\n\n /**\n * Creates an IN condition for type-safe list membership testing.\n * Tests if the specified attribute value matches any value in the provided list.\n * Supports up to 100 values in the list as per DynamoDB limitations.\n *\n * @param attr - The attribute path to compare (with full type safety)\n * @param values - Array of values to test against (must match attribute type, max 100 items)\n * @returns A condition that evaluates to true when attr matches any value in the list\n *\n * @example\n * ```typescript\n * interface User { status: string; role: string; priority: number; }\n *\n * // Status filtering\n * op.inArray(\"status\", [\"ACTIVE\", \"PENDING\", \"PROCESSING\"]) // status IN (\"ACTIVE\", \"PENDING\", \"PROCESSING\")\n *\n * // Role-based access\n * op.inArray(\"role\", [\"admin\", \"moderator\", \"editor\"]) // role IN (\"admin\", \"moderator\", \"editor\")\n *\n * // Priority levels\n * op.inArray(\"priority\", [1, 2, 3]) // priority IN (1, 2, 3)\n * ```\n *\n * @throws {Error} When values array is empty or contains more than 100 items\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Comparators AWS DynamoDB - IN}\n */\n inArray: <K extends Path<T>>(attr: K, values: PathType<T, K>[]) => Condition;\n\n /**\n * Creates a begins_with condition for type-safe string prefix testing.\n * Tests if the specified string attribute starts with the provided substring.\n * Only works with string attributes - will fail on other data types.\n *\n * @param attr - The string attribute path to test (with full type safety)\n * @param value - The prefix string to test for (must match attribute type)\n * @returns A condition that evaluates to true when attr starts with value\n *\n * @example\n * ```typescript\n * interface User { email: string; name: string; id: string; }\n *\n * // Email domain filtering\n * op.beginsWith(\"email\", \"admin@\") // begins_with(email, \"admin@\")\n *\n * // Name prefix search\n * op.beginsWith(\"name\", \"John\") // begins_with(name, \"John\")\n *\n * // ID pattern matching\n * op.beginsWith(\"id\", \"USER#\") // begins_with(id, \"USER#\")\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - begins_with}\n */\n beginsWith: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates a contains condition for type-safe substring or set membership testing.\n * For strings: tests if the attribute contains the specified substring.\n * For sets: tests if the set contains the specified element.\n *\n * @param attr - The attribute path to test (with full type safety)\n * @param value - The substring or element to search for (must match attribute type)\n * @returns A condition that evaluates to true when attr contains value\n *\n * @example\n * ```typescript\n * interface Post { content: string; tags: Set<string>; categories: string[]; }\n *\n * // Substring search in content\n * op.contains(\"content\", \"important\") // contains(content, \"important\")\n *\n * // Tag membership (for DynamoDB String Sets)\n * op.contains(\"tags\", \"featured\") // contains(tags, \"featured\")\n *\n * // Category search (for string arrays stored as lists)\n * op.contains(\"categories\", \"technology\") // contains(categories, \"technology\")\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - contains}\n */\n contains: <K extends Path<T>>(attr: K, value: PathType<T, K>) => Condition;\n\n /**\n * Creates an attribute_exists condition for type-safe attribute presence testing.\n * Tests if the specified attribute exists in the item, regardless of its value.\n * Useful for filtering items that have optional attributes populated.\n *\n * @param attr - The attribute path to test for existence (with full type safety)\n * @returns A condition that evaluates to true when the attribute exists\n *\n * @example\n * ```typescript\n * interface User { email: string; phone?: string; profile?: { avatar?: string; }; }\n *\n * // Check for optional fields\n * op.attributeExists(\"phone\") // attribute_exists(phone)\n *\n * // Check for nested optional attributes\n * op.attributeExists(\"profile.avatar\") // attribute_exists(profile.avatar)\n *\n * // Useful in combination with other conditions\n * op.and(\n * op.eq(\"status\", \"ACTIVE\"),\n * op.attributeExists(\"email\") // Only active users with email\n * )\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - attribute_exists}\n */\n attributeExists: <K extends Path<T>>(attr: K) => Condition;\n\n /**\n * Creates an attribute_not_exists condition for type-safe attribute absence testing.\n * Tests if the specified attribute does not exist in the item.\n * Useful for conditional writes to prevent overwriting existing data.\n *\n * @param attr - The attribute path to test for absence (with full type safety)\n * @returns A condition that evaluates to true when the attribute does not exist\n *\n * @example\n * ```typescript\n * interface User { id: string; email: string; deletedAt?: string; }\n *\n * // Ensure item hasn't been soft-deleted\n * op.attributeNotExists(\"deletedAt\") // attribute_not_exists(deletedAt)\n *\n * // Prevent duplicate creation\n * op.attributeNotExists(\"id\") // attribute_not_exists(id)\n *\n * // Conditional updates\n * op.and(\n * op.eq(\"status\", \"PENDING\"),\n * op.attributeNotExists(\"processedAt\") // Only unprocessed items\n * )\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions AWS DynamoDB - attribute_not_exists}\n */\n attributeNotExists: <K extends Path<T>>(attr: K) => Condition;\n\n /**\n * Combines multiple conditions with logical AND operator.\n * All provided conditions must evaluate to true for the AND condition to be true.\n * Supports any number of conditions as arguments.\n *\n * @param conditions - Variable number of conditions to combine with AND\n * @returns A condition that evaluates to true when all input conditions are true\n *\n * @example\n * ```typescript\n * interface User { status: string; age: number; role: string; verified: boolean; }\n *\n * // Multiple criteria\n * op.and(\n * op.eq(\"status\", \"ACTIVE\"),\n * op.gt(\"age\", 18),\n * op.eq(\"verified\", true)\n * ) // status = \"ACTIVE\" AND age > 18 AND verified = true\n *\n * // Complex business logic\n * op.and(\n * op.inArray(\"role\", [\"admin\", \"moderator\"]),\n * op.attributeExists(\"permissions\"),\n * op.ne(\"status\", \"SUSPENDED\")\n * )\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - AND}\n */\n and: (...conditions: Condition[]) => Condition;\n\n /**\n * Combines multiple conditions with logical OR operator.\n * At least one of the provided conditions must evaluate to true for the OR condition to be true.\n * Supports any number of conditions as arguments.\n *\n * @param conditions - Variable number of conditions to combine with OR\n * @returns A condition that evaluates to true when any input condition is true\n *\n * @example\n * ```typescript\n * interface Order { status: string; priority: string; urgent: boolean; }\n *\n * // Alternative statuses\n * op.or(\n * op.eq(\"status\", \"PENDING\"),\n * op.eq(\"status\", \"PROCESSING\"),\n * op.eq(\"status\", \"SHIPPED\")\n * ) // status = \"PENDING\" OR status = \"PROCESSING\" OR status = \"SHIPPED\"\n *\n * // High priority items\n * op.or(\n * op.eq(\"priority\", \"HIGH\"),\n * op.eq(\"urgent\", true)\n * )\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - OR}\n */\n or: (...conditions: Condition[]) => Condition;\n\n /**\n * Negates a condition with logical NOT operator.\n * Inverts the boolean result of the provided condition.\n *\n * @param condition - The condition to negate\n * @returns A condition that evaluates to true when the input condition is false\n *\n * @example\n * ```typescript\n * interface User { status: string; role: string; banned: boolean; }\n *\n * // Exclude specific status\n * op.not(op.eq(\"status\", \"DELETED\")) // NOT status = \"DELETED\"\n *\n * // Complex negation\n * op.not(\n * op.and(\n * op.eq(\"role\", \"guest\"),\n * op.eq(\"banned\", true)\n * )\n * ) // NOT (role = \"guest\" AND banned = true)\n *\n * // Exclude multiple values\n * op.not(op.inArray(\"status\", [\"DELETED\", \"ARCHIVED\"]))\n * ```\n *\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Logical AWS DynamoDB - NOT}\n */\n not: (condition: Condition) => Condition;\n};\n\n/**\n * Primary key type for QUERY operations.\n * Allows building complex key conditions for the sort key.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html AWS DynamoDB - Query Operations}\n *\n * @example\n * // Query items with a specific partition key and sort key prefix\n * table.query({\n * pk: \"USER#123\",\n * sk: op => op.beginsWith(\"ORDER#2023\")\n * })\n *\n * @example\n * // Query items within a specific sort key range\n * table.query({\n * pk: \"USER#123\",\n * sk: op => op.between(\"ORDER#2023-01\", \"ORDER#2023-12\")\n * })\n */\nexport type PrimaryKey = {\n /** Partition key value */\n pk: string;\n /** Optional sort key condition builder */\n sk?: (op: KeyConditionOperator) => Condition;\n};\n\n/**\n * Primary key type for GET and DELETE operations.\n * Used when you need to specify exact key values without conditions.\n * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html AWS DynamoDB - Working with Items}\n *\n * @example\n * // Get a specific item by its complete primary key\n * table.get({\n * pk: \"USER#123\",\n * sk: \"PROFILE#123\"\n * })\n *\n * @example\n * // Delete a specific item by its complete primary key\n * table.delete({\n * pk: \"USER#123\",\n * sk: \"ORDER#456\"\n * })\n */\nexport type PrimaryKeyWithoutExpression = {\n /** Partition key value */\n pk: string;\n /** Optional sort key value */\n sk?: string;\n};\n","import type { DynamoItem, TableConfig } from \"../types\";\nimport type { PaginationResult, QueryBuilderInterface } from \"./builder-types\";\n\n/**\n * A utility class for handling DynamoDB pagination.\n * Use this class when you need to:\n * - Browse large collections of dinosaurs\n * - Review extensive security logs\n * - Analyze habitat inspection history\n * - Process feeding schedules\n *\n * The paginator maintains internal state and automatically handles:\n * - Page boundaries\n * - Result set limits\n * - Continuation tokens\n *\n * @example\n * ```typescript\n * // List all velociraptors with pagination\n * const paginator = new QueryBuilder(executor, eq('species', 'Velociraptor'))\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .paginate(10);\n *\n * // Process each page of dinosaurs\n * while (paginator.hasNextPage()) {\n * const page = await paginator.getNextPage();\n * console.log(`Processing page ${page.page} of velociraptors`);\n *\n * for (const raptor of page.items) {\n * console.log(`- ${raptor.id}: Health=${raptor.stats.health}`);\n * }\n * }\n * ```\n *\n * @typeParam T - The type of items being paginated\n * @typeParam TConfig - The table configuration type\n */\nexport class Paginator<T extends DynamoItem, TConfig extends TableConfig = TableConfig> {\n private queryBuilder: QueryBuilderInterface<T, TConfig>;\n private readonly pageSize?: number;\n private currentPage = 0;\n private lastEvaluatedKey?: DynamoItem;\n private hasMorePages = true;\n private totalItemsRetrieved = 0;\n private readonly overallLimit?: number;\n\n constructor(queryBuilder: QueryBuilderInterface<T, TConfig>, pageSize?: number) {\n this.queryBuilder = queryBuilder;\n this.pageSize = pageSize;\n // Store the overall limit from the query builder if it exists\n this.overallLimit = queryBuilder.getLimit();\n }\n\n /**\n * Gets the current page number (1-indexed).\n *\n * @example\n * ```ts\n * const paginator = new QueryBuilder(executor, eq('species', 'Tyrannosaurus'))\n * .paginate(5);\n *\n * await paginator.getNextPage();\n * console.log(`Reviewing T-Rex group ${paginator.getCurrentPage()}`);\n * ```\n *\n * @returns The current page number, starting from 1\n */\n public getCurrentPage(): number {\n return this.currentPage;\n }\n\n /**\n * Checks if there are more pages of dinosaurs or habitats to process.\n *\n * This method takes into account both:\n * - DynamoDB's lastEvaluatedKey mechanism\n * - Any overall limit set on the query\n *\n * @example\n * ```ts\n * // Process all security incidents\n * const paginator = new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))\n * .sortDescending()\n * .paginate(10);\n *\n * while (paginator.hasNextPage()) {\n * const page = await paginator.getNextPage();\n * for (const incident of page.items) {\n * await processSecurityBreach(incident);\n * }\n * console.log(`Processed incidents page ${page.page}`);\n * }\n * ```\n *\n * @returns true if there are more pages available, false otherwise\n */\n public hasNextPage(): boolean {\n // If we have an overall limit and we've already retrieved that many items, there are no more pages\n if (this.overallLimit !== undefined && this.totalItemsRetrieved >= this.overallLimit) {\n return false;\n }\n return this.hasMorePages;\n }\n\n /**\n * Retrieves the next page of dinosaurs or habitats from DynamoDB.\n *\n * This method handles:\n * - Automatic continuation between groups\n * - Respect for park capacity limits\n * - Group size adjustments for safety\n *\n * @example\n * ```ts\n * const paginator = new QueryBuilder(executor, eq('species', 'Velociraptor'))\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .paginate(5);\n *\n * // Check first raptor group\n * const page1 = await paginator.getNextPage();\n * console.log(`Found ${page1.items.length} active raptors`);\n *\n * // Continue inspection if more groups exist\n * if (page1.hasNextPage) {\n * const page2 = await paginator.getNextPage();\n * console.log(`Inspecting raptor group ${page2.page}`);\n *\n * for (const raptor of page2.items) {\n * await performHealthCheck(raptor);\n * }\n * }\n * ```\n *\n * @returns A promise that resolves to a PaginationResult containing:\n * - items: The dinosaurs/habitats for this page\n * - hasNextPage: Whether more groups exist\n * - page: The current group number\n * - lastEvaluatedKey: DynamoDB's continuation token\n */\n public async getNextPage(): Promise<PaginationResult<T>> {\n if (!this.hasNextPage()) {\n return {\n items: [],\n hasNextPage: false,\n page: this.currentPage,\n };\n }\n\n // Calculate how many items to fetch for this page\n let effectivePageSize = this.pageSize;\n\n // If we have an overall limit, make sure we don't fetch more than what's left\n if (this.overallLimit !== undefined) {\n const remainingItems = this.overallLimit - this.totalItemsRetrieved;\n if (remainingItems <= 0) {\n return {\n items: [],\n hasNextPage: false,\n page: this.currentPage,\n };\n }\n if (effectivePageSize !== undefined) {\n effectivePageSize = Math.min(effectivePageSize, remainingItems);\n } else {\n effectivePageSize = remainingItems;\n }\n }\n\n // Clone the query builder to avoid modifying the original\n const query = this.queryBuilder.clone();\n\n // Only set limit if we have an effective page size (not automatic paging)\n if (effectivePageSize !== undefined) {\n query.limit(effectivePageSize);\n }\n\n // Apply the last evaluated key if we have one\n if (this.lastEvaluatedKey) {\n query.startFrom(this.lastEvaluatedKey);\n }\n\n // Execute the query and get the first page from the generator\n const generator = await query.execute();\n const items: T[] = [];\n\n // Take items up to the effective page size\n let itemCount = 0;\n for await (const item of generator) {\n if (effectivePageSize !== undefined && itemCount >= effectivePageSize) {\n break;\n }\n items.push(item);\n itemCount++;\n }\n\n // Get the last evaluated key from the generator\n const lastEvaluatedKey = generator.getLastEvaluatedKey();\n\n const result = { items, lastEvaluatedKey };\n\n // Update pagination state\n this.currentPage += 1;\n this.lastEvaluatedKey = result.lastEvaluatedKey;\n this.totalItemsRetrieved += result.items.length;\n\n // Determine if there are more pages\n // We have more pages if:\n // 1. DynamoDB returned a lastEvaluatedKey AND\n // 2. We haven't hit our overall limit (if one exists)\n this.hasMorePages =\n !!result.lastEvaluatedKey && (this.overallLimit === undefined || this.totalItemsRetrieved < this.overallLimit);\n\n return {\n items: result.items,\n lastEvaluatedKey: result.lastEvaluatedKey,\n hasNextPage: this.hasNextPage(),\n page: this.currentPage,\n };\n }\n\n /**\n * Gets all remaining dinosaurs or habitats and combines them into a single array.\n *\n * @example\n * ```ts\n * // Get complete carnivore inventory\n * const paginator = new QueryBuilder(executor, eq('diet', 'CARNIVORE'))\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .paginate(10);\n *\n * try {\n * const allCarnivores = await paginator.getAllPages();\n * console.log(`Park contains ${allCarnivores.length} active carnivores`);\n *\n * // Calculate total threat level\n * const totalThreat = allCarnivores.reduce(\n * (sum, dino) => sum + dino.stats.threatLevel,\n * 0\n * );\n * console.log(`Total threat level: ${totalThreat}`);\n * } catch (error) {\n * console.error('Failed to complete carnivore census:', error);\n * }\n * ```\n *\n * @returns A promise that resolves to an array containing all remaining items\n */\n public async getAllPages(): Promise<T[]> {\n const allItems: T[] = [];\n\n while (this.hasNextPage()) {\n const result = await this.getNextPage();\n allItems.push(...result.items);\n }\n\n return allItems;\n }\n}\n","import {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n between,\n inArray,\n beginsWith,\n contains,\n attributeExists,\n attributeNotExists,\n and,\n or,\n not,\n type Condition,\n type ConditionOperator,\n} from \"../conditions\";\nimport { Paginator } from \"./paginator\";\nimport type { DynamoItem, GSINames, TableConfig } from \"../types\";\nimport type { FilterBuilderInterface } from \"./builder-types\";\nimport type { ResultIterator } from \"./result-iterator\";\nimport type { Path } from \"./types\";\n\n/**\n * Configuration options for DynamoDB filter operations.\n * These are common options shared between query and scan operations.\n */\nexport interface FilterOptions {\n /** Filter conditions applied to results */\n filter?: Condition;\n /** Maximum number of items to return */\n limit?: number;\n /** Name of the Global Secondary Index to use */\n indexName?: string;\n /** Whether to use strongly consistent reads */\n consistentRead?: boolean;\n /** List of attributes to return in the result */\n projection?: string[];\n /** Token for starting the operation from a specific point */\n lastEvaluatedKey?: DynamoItem;\n}\n\n/**\n * Abstract base builder for creating DynamoDB filter operations.\n * This class provides common functionality for both Query and Scan operations.\n *\n * The builder supports:\n * - Type-safe GSI selection\n * - Complex filter conditions\n * - Pagination\n * - Consistent reads\n * - Attribute projection\n *\n * @typeParam T - The type of items being filtered\n * @typeParam TConfig - The table configuration type for type-safe GSI selection\n */\nexport abstract class FilterBuilder<T extends DynamoItem, TConfig extends TableConfig = TableConfig>\n implements FilterBuilderInterface<T, TConfig>\n{\n protected options: FilterOptions = {};\n protected selectedFields: Set<string> = new Set();\n\n /**\n * Sets the maximum number of items to return.\n *\n * Note: This limit applies to the items that match the key condition\n * before any filter expressions are applied.\n *\n * @example\n * ```typescript\n * // Get first 10 dinosaurs\n * const result = await builder\n * .limit(10)\n * .execute();\n * ```\n *\n * @param limit - Maximum number of items to return\n * @returns The builder instance for method chaining\n */\n limit(limit: number): this {\n this.options.limit = limit;\n return this;\n }\n\n /**\n * Gets the current limit set on the operation.\n * This is used internally by the paginator to manage result sets.\n *\n * @returns The current limit or undefined if no limit is set\n */\n getLimit(): number | undefined {\n return this.options.limit;\n }\n\n /**\n * Specifies a Global Secondary Index (GSI) to use for the operation.\n *\n * @example\n * ```typescript\n * // Find all dinosaurs of a specific species\n * builder\n * .useIndex('species-status-index')\n * .filter(op => op.eq('status', 'ACTIVE'));\n *\n * // Search high-security habitats\n * builder\n * .useIndex('security-level-index')\n * .filter(op =>\n * op.and([\n * op.gt('securityLevel', 8),\n * op.eq('status', 'OPERATIONAL')\n * ])\n * );\n * ```\n *\n * @param indexName - The name of the GSI to use (type-safe based on table configuration)\n * @returns The builder instance for method chaining\n */\n useIndex<I extends GSINames<TConfig>>(indexName: I): this {\n this.options.indexName = indexName as string;\n return this;\n }\n\n /**\n * Sets whether to use strongly consistent reads for the operation.\n *\n * Note:\n * - Consistent reads are not available on GSIs\n * - Consistent reads consume twice the throughput\n * - Default is eventually consistent reads\n *\n * @example\n * ```typescript\n * // Check immediate dinosaur status\n * const result = await builder\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .consistentRead()\n * .execute();\n *\n * // Monitor security breaches\n * const result = await builder\n * .useIndex('primary-index')\n * .consistentRead(isEmergencyMode)\n * .execute();\n * ```\n *\n * @param consistentRead - Whether to use consistent reads (defaults to true)\n * @returns The builder instance for method chaining\n */\n consistentRead(consistentRead = true): this {\n this.options.consistentRead = consistentRead;\n return this;\n }\n\n /**\n * Adds a filter expression to refine the operation results.\n *\n * @example\n * ```typescript\n * // Find aggressive carnivores\n * builder.filter(op =>\n * op.and([\n * op.eq('diet', 'CARNIVORE'),\n * op.gt('aggressionLevel', 7),\n * op.eq('status', 'ACTIVE')\n * ])\n * );\n *\n * // Search suitable breeding habitats\n * builder.filter(op =>\n * op.and([\n * op.between('temperature', 25, 30),\n * op.lt('currentOccupants', 3),\n * op.eq('quarantineStatus', 'CLEAR')\n * ])\n * );\n * ```\n *\n * @param condition - Either a Condition object or a callback function that builds the condition\n * @returns The builder instance for method chaining\n */\n filter(condition: Condition | ((op: ConditionOperator<T>) => Condition)): this {\n if (typeof condition === \"function\") {\n const conditionOperator: ConditionOperator<T> = {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n between,\n inArray,\n beginsWith,\n contains,\n attributeExists,\n attributeNotExists,\n and,\n or,\n not,\n };\n this.options.filter = condition(conditionOperator);\n } else {\n this.options.filter = condition;\n }\n return this;\n }\n\n /**\n * Specifies which attributes to return in the results.\n *\n * @example\n * ```typescript\n * // Get basic dinosaur info\n * builder.select([\n * 'species',\n * 'status',\n * 'stats.health',\n * 'stats.aggressionLevel'\n * ]);\n *\n * // Monitor habitat conditions\n * builder\n * .select('securityStatus')\n * .select([\n * 'currentOccupants',\n * 'temperature',\n * 'lastInspectionDate'\n * ]);\n * ```\n *\n * @param fields - A single field name or an array of field names to return\n * @returns The builder instance for method chaining\n */\n select<K extends Path<T>>(fields: K | K[]): this {\n if (typeof fields === \"string\") {\n this.selectedFields.add(fields);\n } else if (Array.isArray(fields)) {\n for (const field of fields) {\n this.selectedFields.add(field);\n }\n }\n\n this.options.projection = Array.from(this.selectedFields);\n return this;\n }\n\n /**\n * Creates a paginator that handles DynamoDB pagination automatically.\n * The paginator handles:\n * - Tracking the last evaluated key\n * - Managing page boundaries\n * - Respecting overall query limits\n *\n * @example\n * ```typescript\n * // Create a paginator for dinosaur records with specific page size\n * const paginator = builder\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .paginate(10);\n *\n * // Create a paginator with automatic DynamoDB paging (no page size limit)\n * const autoPaginator = builder\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .paginate();\n *\n * // Process pages of dinosaur results\n * while (paginator.hasNextPage()) {\n * const page = await paginator.getNextPage();\n * console.log(`Processing page ${page.page}, count: ${page.items.length}`);\n * // Process dinosaur data\n * }\n * ```\n *\n * @param pageSize - The number of items to return per page. If not provided, DynamoDB will automatically determine page sizes.\n * @returns A Paginator instance that manages the pagination state\n * @see Paginator for more pagination control options\n */\n paginate(pageSize?: number): Paginator<T, TConfig> {\n return new Paginator<T, TConfig>(this, pageSize);\n }\n\n /**\n * Sets the starting point using a previous lastEvaluatedKey.\n *\n * Note: This method is typically used for manual pagination.\n * For automatic pagination, use the paginate() method instead.\n *\n * @example\n * ```typescript\n * // First batch of dinosaurs\n * const result1 = await builder\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .limit(5)\n * .execute();\n *\n * const lastKey = result1.getLastEvaluatedKey();\n * if (lastKey) {\n * // Continue listing dinosaurs\n * const result2 = await builder\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .startFrom(lastKey)\n * .limit(5)\n * .execute();\n *\n * const items = await result2.toArray();\n * console.log('Additional dinosaurs:', items);\n * }\n * ```\n *\n * @param lastEvaluatedKey - The exclusive start key from a previous result\n * @returns The builder instance for method chaining\n */\n startFrom(lastEvaluatedKey: DynamoItem): this {\n this.options.lastEvaluatedKey = lastEvaluatedKey;\n return this;\n }\n\n /**\n * Creates a deep clone of this builder instance.\n *\n * This is particularly useful when:\n * - Implementing pagination (used internally by paginate())\n * - Creating operation templates\n * - Running multiple variations of an operation\n *\n * @example\n * ```typescript\n * // Create base dinosaur query\n * const baseBuilder = builder\n * .useIndex('status-index')\n * .select(['id', 'status', 'location']);\n *\n * // Check active dinosaurs\n * const activeRaptors = baseBuilder.clone()\n * .filter(op => op.eq('status', 'HUNTING'))\n * .execute();\n *\n * // Check contained dinosaurs\n * const containedRaptors = baseBuilder.clone()\n * .filter(op => op.eq('status', 'CONTAINED'))\n * .execute();\n * ```\n *\n * @returns A new builder instance with the same configuration\n */\n abstract clone(): FilterBuilderInterface<T, TConfig>;\n\n /**\n * Executes the operation against DynamoDB and returns a generator that behaves like an array.\n * This method must be implemented by subclasses to handle\n * their specific execution logic.\n */\n abstract execute(): Promise<ResultIterator<T, TConfig>>;\n}\n","import type { DynamoItem, TableConfig } from \"../types\";\nimport type { QueryBuilderInterface } from \"./builder-types\";\n\n/**\n * Function type for executing DynamoDB operations and returning raw results.\n */\ntype DirectExecutor<T extends DynamoItem> = () => Promise<{ items: T[]; lastEvaluatedKey?: DynamoItem }>;\n\n/**\n * Minimal result generator that provides async iteration over DynamoDB results with automatic pagination.\n *\n * @example\n * ```typescript\n * const results = await queryBuilder.execute();\n *\n * for await (const item of results) {\n * console.log(item);\n * }\n * ```\n */\nexport class ResultIterator<T extends DynamoItem, TConfig extends TableConfig = TableConfig> {\n private lastEvaluatedKey?: DynamoItem | null;\n private itemsYielded = 0;\n private readonly overallLimit?: number;\n\n constructor(\n private queryBuilder: QueryBuilderInterface<T, TConfig>,\n private directExecutor: DirectExecutor<T>,\n ) {\n this.overallLimit = queryBuilder.getLimit();\n }\n\n /**\n * Async iterator with automatic pagination\n */\n async *[Symbol.asyncIterator](): AsyncIterableIterator<T> {\n let hasMorePages = true;\n\n while (hasMorePages) {\n const result = await this.directExecutor();\n\n for (const item of result.items) {\n // Check if we've reached the overall limit\n if (this.overallLimit !== undefined && this.itemsYielded >= this.overallLimit) {\n return;\n }\n \n yield item;\n this.itemsYielded++;\n }\n\n // Update lastEvaluatedKey, but preserve the last non-null value\n if (result.lastEvaluatedKey !== null && result.lastEvaluatedKey !== undefined) {\n this.lastEvaluatedKey = result.lastEvaluatedKey;\n // Update the query builder's options for the next iteration\n this.queryBuilder.startFrom(result.lastEvaluatedKey);\n } else if (result.lastEvaluatedKey === null) {\n // Only set to null if we haven't seen a lastEvaluatedKey yet\n if (this.lastEvaluatedKey === undefined) {\n this.lastEvaluatedKey = null;\n }\n }\n \n // Stop if we've reached the overall limit or no more pages\n hasMorePages = !!result.lastEvaluatedKey && \n (this.overallLimit === undefined || this.itemsYielded < this.overallLimit);\n }\n }\n\n /**\n * Convert to array (loads all pages).\n *\n * ```ts\n * const result = await table.query({ pk: \"foo\" }).execute();\n * const allItemsFromDynamo = await result.toArray();\n * ```\n *\n * Note: This will load all pages into memory. For large datasets, consider using async iteration instead.\n *```ts\n * const result = await table.query({ pk: \"foo\" }).execute();\n * for await (const item of result) {\n * // Process each item\n * }\n * ```\n */\n async toArray(): Promise<T[]> {\n const items: T[] = [];\n for await (const item of this) {\n items.push(item);\n }\n return items;\n }\n\n /**\n * Get the last evaluated key\n */\n getLastEvaluatedKey(): DynamoItem | undefined {\n return this.lastEvaluatedKey === null ? undefined : this.lastEvaluatedKey;\n }\n}\n","import type { Condition } from \"../conditions\";\nimport { FilterBuilder, type FilterOptions } from \"./filter-builder\";\nimport type { DynamoItem, TableConfig } from \"../types\";\nimport type { QueryBuilderInterface } from \"./builder-types\";\nimport { ResultIterator } from \"./result-iterator\";\n\n/**\n * Configuration options for DynamoDB query operations.\n * Extends the base FilterOptions with query-specific options.\n */\nexport interface QueryOptions extends FilterOptions {\n /** Condition for the sort key in the table or index */\n sortKeyCondition?: Condition;\n /** Direction of sort key traversal (true for ascending, false for descending) */\n scanIndexForward?: boolean;\n}\n\n/**\n * Function type for executing DynamoDB query operations.\n * @typeParam T - The type of items being queried\n */\ntype QueryExecutor<T extends DynamoItem> = (\n keyCondition: Condition,\n options: QueryOptions,\n) => Promise<{ items: T[]; lastEvaluatedKey?: Record<string, unknown> }>;\n\n/**\n * Builder for creating DynamoDB query operations.\n *\n * The builder supports:\n * - Type-safe GSI selection\n * - Complex filter conditions\n * - Automatic pagination handling\n * - Consistent reads\n * - Forward and reverse sorting\n *\n * @example\n * ```typescript\n * // Simple query\n * const result = await new QueryBuilder(executor, eq('userId', '123'))\n * .execute();\n *\n * // Complex query with GSI and filtering\n * const result = await new QueryBuilder(executor, eq('status', 'ACTIVE'))\n * .useIndex('status-index')\n * .filter(op => op.beginsWith('name', 'John'))\n * .select(['id', 'name', 'email'])\n * .sortDescending()\n * .limit(10)\n * .execute();\n *\n * // Query with pagination\n * const paginator = new QueryBuilder(executor, eq('type', 'order'))\n * .paginate(25);\n *\n * while (paginator.hasNextPage()) {\n * const page = await paginator.getNextPage();\n * // Process page.items\n * }\n * ```\n *\n * @typeParam T - The type of items being queried\n * @typeParam TConfig - The table configuration type for type-safe GSI selection\n */\nexport class QueryBuilder<T extends DynamoItem, TConfig extends TableConfig = TableConfig>\n extends FilterBuilder<T, TConfig>\n implements QueryBuilderInterface<T, TConfig>\n{\n private readonly keyCondition: Condition;\n protected override options: QueryOptions = {};\n protected readonly executor: QueryExecutor<T>;\n\n constructor(executor: QueryExecutor<T>, keyCondition: Condition) {\n super();\n this.executor = executor;\n this.keyCondition = keyCondition;\n }\n\n /**\n * Sets the maximum number of items to return from the query.\n *\n * Note: This is the default behavior if no sort order is specified.\n *\n * @example\n * ```typescript\n * // Get orders in chronological order\n * const result = await new QueryBuilder(executor, eq('userId', '123'))\n * .sortAscending()\n * .execute();\n *\n * // Get events from oldest to newest\n * const result = await new QueryBuilder(executor, eq('entityId', 'order-123'))\n * .useIndex('entity-timestamp-index')\n * .sortAscending()\n * .execute();\n * ```\n *\n * @returns The builder instance for method chaining\n */\n /**\n * Sets the query to return items in ascending order by sort key.\n *\n * @example\n * ```typescript\n * // List dinosaurs by age\n * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))\n * .useIndex('age-index')\n * .sortAscending()\n * .execute();\n *\n * // View incidents chronologically\n * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))\n * .useIndex('date-index')\n * .sortAscending()\n * .execute();\n * ```\n *\n * @returns The builder instance for method chaining\n */\n sortAscending(): this {\n this.options.scanIndexForward = true;\n return this;\n }\n\n /**\n * Sets the query to return items in descending order by sort key.\n *\n * @example\n * ```typescript\n * // Get most recent security incidents\n * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))\n * .useIndex('date-index')\n * .sortDescending()\n * .limit(10)\n * .execute();\n *\n * // Check latest dinosaur activities\n * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))\n * .useIndex('activity-time-index')\n * .filter(op => op.eq('status', 'ACTIVE'))\n * .sortDescending()\n * .execute();\n * ```\n *\n * @returns The builder instance for method chaining\n */\n sortDescending(): this {\n this.options.scanIndexForward = false;\n return this;\n }\n\n /**\n * Creates a deep clone of this QueryBuilder instance.\n *\n * This is particularly useful when:\n * - Implementing pagination (used internally by paginate())\n * - Creating query templates\n * - Running multiple variations of a query\n *\n * @example\n * ```typescript\n * // Create base dinosaur query\n * const baseQuery = new QueryBuilder(executor, eq('species', 'Velociraptor'))\n * .useIndex('status-index')\n * .select(['id', 'status', 'location']);\n *\n * // Check active dinosaurs\n * const activeRaptors = baseQuery.clone()\n * .filter(op => op.eq('status', 'HUNTING'))\n * .execute();\n *\n * // Check contained dinosaurs\n * const containedRaptors = baseQuery.clone()\n * .filter(op => op.eq('status', 'CONTAINED'))\n * .execute();\n *\n * // Check sedated dinosaurs\n * const sedatedRaptors = baseQuery.clone()\n * .filter(op => op.eq('status', 'SEDATED'))\n * .execute();\n * ```\n *\n * @returns A new QueryBuilder instance with the same configuration\n */\n clone(): QueryBuilder<T, TConfig> {\n const clone = new QueryBuilder<T, TConfig>(this.executor, this.keyCondition);\n clone.options = { ...this.options };\n clone.selectedFields = new Set(this.selectedFields);\n return clone;\n }\n\n /**\n * Executes the query against DynamoDB and returns a generator that behaves like an array.\n *\n * The generator automatically handles pagination and provides array-like methods\n * for processing results efficiently without loading everything into memory at once.\n *\n * @example\n * ```typescript\n * try {\n * // Find active carnivores with automatic pagination\n * const results = await new QueryBuilder(executor, eq('habitatId', 'PADDOCK-A'))\n * .useIndex('species-status-index')\n * .filter(op =>\n * op.and([\n * op.eq('diet', 'CARNIVORE'),\n * op.eq('status', 'ACTIVE'),\n * op.gt('aggressionLevel', 7)\n * ])\n * )\n * .sortDescending()\n * .execute();\n *\n * // Use like an array with automatic pagination\n * for await (const dinosaur of results) {\n * console.log(`Processing ${dinosaur.name}`);\n * }\n *\n * // Or convert to array and use array methods\n * const allItems = await results.toArray();\n * const dangerousOnes = allItems.filter(dino => dino.aggressionLevel > 9);\n * const totalCount = allItems.length;\n * } catch (error) {\n * console.error('Security scan failed:', error);\n * }\n * ```\n *\n * @returns A promise that resolves to a ResultGenerator that behaves like an array\n */\n async execute(): Promise<ResultIterator<T, TConfig>> {\n const directExecutor = () => this.executor(this.keyCondition, this.options);\n return new ResultIterator(this, directExecutor);\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import '../conditions-3ae5znV_.cjs';
2
- export { Q as QueryBuilder, a as QueryOptions } from '../query-builder-DFkxojBM.cjs';
2
+ export { Q as QueryBuilder, a as QueryOptions } from '../query-builder-BALW-vW_.cjs';
3
3
  import '../types.cjs';
4
4
  import '../builder-types-BTVhQSHI.cjs';
5
5
  import './paginator.cjs';
@@ -1,5 +1,5 @@
1
1
  import '../conditions-BtynAviC.js';
2
- export { Q as QueryBuilder, a as QueryOptions } from '../query-builder-CaHzZmDf.js';
2
+ export { Q as QueryBuilder, a as QueryOptions } from '../query-builder-BK9eM-gt.js';
3
3
  import '../types.js';
4
4
  import '../builder-types-CzuLR4Th.js';
5
5
  import './paginator.js';