@@ -4,16 +4,87 @@ import { transformValue } from '@lib/entity/helpers/transformValues';
44import { EntityKey , EntityValue } from '@lib/entity/types' ;
55import { BASE_OPERATOR , OPERATORS , Operators , ValidationError } from '@lib/utils' ;
66
7+ /**
8+ * Condition builder for DynamoDB condition expressions.
9+ *
10+ * This class provides a fluent interface for building complex condition expressions
11+ * that can be used in DynamoDB operations like PutItem, UpdateItem, and DeleteItem.
12+ * It supports all DynamoDB condition operators and functions with type safety.
13+ *
14+ * @template E - The entity class type
15+ *
16+ * @example
17+ * ```typescript
18+ * // Basic conditions
19+ * const condition = new Condition(User)
20+ * .attribute('status').eq('active')
21+ * .attribute('age').gt(18);
22+ *
23+ * // Complex conditions with grouping
24+ * const condition = new Condition(User)
25+ * .attribute('status').eq('active')
26+ * .parenthesis(
27+ * new Condition(User)
28+ * .attribute('age').gt(18)
29+ * .or
30+ * .attribute('role').eq('admin')
31+ * );
32+ *
33+ * // Using with entity manager
34+ * await UserManager.update(
35+ * { id: 'user-123' },
36+ * { status: 'inactive' },
37+ * { condition }
38+ * );
39+ * ```
40+ *
41+ * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html } for DynamoDB condition expressions
42+ * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html } for DynamoDB operators and functions
43+ */
744export default class Condition < E extends typeof Entity > {
45+ /** The entity class for type-safe attribute access */
846 protected entity : E ;
47+ /** The current logical operator (AND or OR) for chaining conditions */
948 protected logicalOperator : typeof BASE_OPERATOR . and | typeof BASE_OPERATOR . or = BASE_OPERATOR . and ;
49+ /** Array of operators that make up the condition expression */
1050 protected operators : Operators ;
1151
52+ /**
53+ * Creates a new Condition instance for the specified entity.
54+ *
55+ * @param entity - The entity class to build conditions for
56+ *
57+ * @example
58+ * ```typescript
59+ * const condition = new Condition(User);
60+ * ```
61+ */
1262 constructor ( entity : E ) {
1363 this . entity = entity ;
1464 this . operators = [ ] ;
1565 }
1666
67+ /**
68+ * Starts building a condition for a specific attribute.
69+ *
70+ * This method returns an object with all available comparison operators
71+ * and functions for the specified attribute, providing a fluent interface
72+ * for building conditions.
73+ *
74+ * @template C - The condition instance type
75+ * @template K - The attribute key type
76+ * @param key - The attribute name to build a condition for
77+ * @returns An object with comparison operators and functions
78+ *
79+ * @example
80+ * ```typescript
81+ * const condition = new Condition(User)
82+ * .attribute('status').eq('active')
83+ * .attribute('age').gt(18)
84+ * .attribute('email').beginsWith('admin@')
85+ * .attribute('tags').contains('premium');
86+ * ```
87+ */
1788 public attribute < C extends this, K extends EntityKey < E > > ( this : C , key : K ) {
1889 this . maybePushLogicalOperator ( ) ;
1990
@@ -137,6 +208,25 @@ export default class Condition<E extends typeof Entity> {
137208 } ;
138209 }
139210
211+ /**
212+ * Wraps a condition in parentheses for grouping.
213+ *
214+ * @param condition - Optional condition to wrap in parentheses
215+ * @returns The condition instance for chaining
216+ *
217+ * @example
218+ * ```typescript
219+ * const condition = new Condition(User)
220+ * .attribute('status').eq('active')
221+ * .and
222+ * .parenthesis(
223+ * new Condition(User)
224+ * .attribute('age').gt(18)
225+ * .or
226+ * .attribute('role').eq('admin')
227+ * );
228+ * ```
229+ */
140230 public parenthesis ( condition ?: Condition < E > ) : this {
141231 if ( condition ) {
142232 this . maybePushLogicalOperator ( ) ;
@@ -145,10 +235,34 @@ export default class Condition<E extends typeof Entity> {
145235 return this ;
146236 }
147237
238+ /**
239+ * Alias for parenthesis() method for grouping conditions.
240+ *
241+ * @param condition - Optional condition to wrap in parentheses
242+ * @returns The condition instance for chaining
243+ */
148244 public group ( condition ?: Condition < E > ) : this {
149245 return this . parenthesis ( condition ) ;
150246 }
151247
248+ /**
249+ * Adds another condition to this condition.
250+ *
251+ * @param condition - The condition to add
252+ * @returns The condition instance for chaining
253+ *
254+ * @example
255+ * ```typescript
256+ * const baseCondition = new Condition(User)
257+ * .attribute('status').eq('active');
258+ *
259+ * const finalCondition = baseCondition
260+ * .condition(
261+ * new Condition(User)
262+ * .attribute('age').gt(18)
263+ * );
264+ * ```
265+ */
152266 public condition ( condition ?: Condition < E > ) : this {
153267 if ( condition ) {
154268 this . maybePushLogicalOperator ( ) ;
@@ -157,51 +271,108 @@ export default class Condition<E extends typeof Entity> {
157271 return this ;
158272 }
159273
274+ /**
275+ * Sets the logical operator to AND for the next condition.
276+ *
277+ * @returns The condition instance for chaining
278+ *
279+ * @example
280+ * ```typescript
281+ * const condition = new Condition(User)
282+ * .attribute('status').eq('active')
283+ * .attribute('age').gt(18);
284+ * ```
285+ */
160286 public get and ( ) : this {
161287 this . logicalOperator = BASE_OPERATOR . and ;
162288 return this ;
163289 }
164290
291+ /**
292+ * Sets the logical operator to OR for the next condition.
293+ *
294+ * @returns The condition instance for chaining
295+ *
296+ * @example
297+ * ```typescript
298+ * const condition = new Condition(User)
299+ * .attribute('status').eq('active')
300+ * .or
301+ * .attribute('role').eq('admin');
302+ * ```
303+ */
165304 public get or ( ) : this {
166305 this . logicalOperator = BASE_OPERATOR . or ;
167306 return this ;
168307 }
169308
309+ /**
310+ * Adds an equality comparison operator.
311+ * @protected
312+ */
170313 protected eq < K extends EntityKey < E > > ( operators : Operators , key : K , value : EntityValue < E , K > ) : this {
171314 operators . push ( ...OPERATORS . eq ( key , transformValue ( this . entity , key , value ) ) ) ;
172315 return this ;
173316 }
174317
318+ /**
319+ * Adds a not equal comparison operator.
320+ * @protected
321+ */
175322 protected ne < K extends EntityKey < E > > ( operators : Operators , key : K , value : EntityValue < E , K > ) : this {
176323 operators . push ( ...OPERATORS . ne ( key , transformValue ( this . entity , key , value ) ) ) ;
177324 return this ;
178325 }
179326
327+ /**
328+ * Adds a less than comparison operator.
329+ * @protected
330+ */
180331 protected lt < K extends EntityKey < E > > ( operators : Operators , key : K , value : EntityValue < E , K > ) : this {
181332 operators . push ( ...OPERATORS . lt ( key , transformValue ( this . entity , key , value ) ) ) ;
182333 return this ;
183334 }
184335
336+ /**
337+ * Adds a less than or equal comparison operator.
338+ * @protected
339+ */
185340 protected le < K extends EntityKey < E > > ( operators : Operators , key : K , value : EntityValue < E , K > ) : this {
186341 operators . push ( ...OPERATORS . le ( key , transformValue ( this . entity , key , value ) ) ) ;
187342 return this ;
188343 }
189344
345+ /**
346+ * Adds a greater than comparison operator.
347+ * @protected
348+ */
190349 protected gt < K extends EntityKey < E > > ( operators : Operators , key : K , value : EntityValue < E , K > ) : this {
191350 operators . push ( ...OPERATORS . gt ( key , transformValue ( this . entity , key , value ) ) ) ;
192351 return this ;
193352 }
194353
354+ /**
355+ * Adds a greater than or equal comparison operator.
356+ * @protected
357+ */
195358 protected ge < K extends EntityKey < E > > ( operators : Operators , key : K , value : EntityValue < E , K > ) : this {
196359 operators . push ( ...OPERATORS . ge ( key , transformValue ( this . entity , key , value ) ) ) ;
197360 return this ;
198361 }
199362
363+ /**
364+ * Adds a begins_with function operator.
365+ * @protected
366+ */
200367 protected beginsWith < K extends EntityKey < E > > ( operators : Operators , key : K , value : EntityValue < E , K > ) : this {
201368 operators . push ( ...OPERATORS . beginsWith ( key , transformValue ( this . entity , key , value ) ) ) ;
202369 return this ;
203370 }
204371
372+ /**
373+ * Adds a BETWEEN operator.
374+ * @protected
375+ */
205376 protected between < K extends EntityKey < E > > (
206377 operators : Operators ,
207378 key : K ,
@@ -214,6 +385,10 @@ export default class Condition<E extends typeof Entity> {
214385 return this ;
215386 }
216387
388+ /**
389+ * Conditionally adds a logical operator between conditions.
390+ * @protected
391+ */
217392 protected maybePushLogicalOperator ( ) : void {
218393 if ( this . operators . length > 0 ) {
219394 this . operators . push ( BASE_OPERATOR . space , this . logicalOperator , BASE_OPERATOR . space ) ;
@@ -222,4 +397,9 @@ export default class Condition<E extends typeof Entity> {
222397 }
223398}
224399
400+ /**
401+ * DynamoDB attribute types enumeration.
402+ *
403+ * @see {@link AttributeType } for the full enumeration
404+ */
225405export { AttributeType } ;
0 commit comments