@ekodb/ekodb-client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/join.js ADDED
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ /**
3
+ * Join support for multi-collection queries
4
+ *
5
+ * This module provides support for joining data across multiple collections,
6
+ * similar to SQL joins but with document-oriented semantics.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.JoinBuilder = void 0;
10
+ /**
11
+ * Builder for constructing join configurations
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Single collection join
16
+ * const join = JoinBuilder.single("users", "user_id", "id", "user");
17
+ *
18
+ * // Multi-collection join
19
+ * const join = JoinBuilder.multi(
20
+ * ["users", "profiles", "settings"],
21
+ * "user_id",
22
+ * "id",
23
+ * "user_info"
24
+ * );
25
+ *
26
+ * // Use in query
27
+ * const query = new QueryBuilder()
28
+ * .eq("status", "active")
29
+ * .join(join)
30
+ * .build();
31
+ * ```
32
+ */
33
+ class JoinBuilder {
34
+ constructor(collections, localField, foreignField, asField) {
35
+ this.config = {
36
+ collections,
37
+ local_field: localField,
38
+ foreign_field: foreignField,
39
+ as_field: asField,
40
+ };
41
+ }
42
+ /**
43
+ * Create a join with a single collection
44
+ *
45
+ * @param collection - Target collection name
46
+ * @param localField - Field in the current collection
47
+ * @param foreignField - Field in the target collection
48
+ * @param asField - Name of the field to store joined data
49
+ */
50
+ static single(collection, localField, foreignField, asField) {
51
+ return new JoinBuilder([collection], localField, foreignField, asField).build();
52
+ }
53
+ /**
54
+ * Create a join with multiple collections
55
+ *
56
+ * @param collections - Array of target collection names
57
+ * @param localField - Field in the current collection
58
+ * @param foreignField - Field in the target collections
59
+ * @param asField - Name of the field to store joined data
60
+ */
61
+ static multi(collections, localField, foreignField, asField) {
62
+ return new JoinBuilder(collections, localField, foreignField, asField).build();
63
+ }
64
+ /**
65
+ * Build the final JoinConfig
66
+ */
67
+ build() {
68
+ return this.config;
69
+ }
70
+ }
71
+ exports.JoinBuilder = JoinBuilder;
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Query Builder for constructing complex queries with fluent API
3
+ */
4
+ export declare enum SortOrder {
5
+ Asc = "asc",
6
+ Desc = "desc"
7
+ }
8
+ export interface Query {
9
+ filter?: any;
10
+ sort?: Array<{
11
+ field: string;
12
+ ascending: boolean;
13
+ }>;
14
+ limit?: number;
15
+ skip?: number;
16
+ join?: any;
17
+ bypass_cache?: boolean;
18
+ bypass_ripple?: boolean;
19
+ }
20
+ /**
21
+ * Fluent API for building complex database queries
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const query = new QueryBuilder()
26
+ * .eq("status", "active")
27
+ * .gt("age", 18)
28
+ * .sortDesc("created_at")
29
+ * .limit(10)
30
+ * .build();
31
+ * ```
32
+ */
33
+ export declare class QueryBuilder {
34
+ private filters;
35
+ private sortFields;
36
+ private _limit?;
37
+ private _skip?;
38
+ private _join?;
39
+ private _bypassCache;
40
+ private _bypassRipple;
41
+ /**
42
+ * Add an equality filter ($eq)
43
+ */
44
+ eq(field: string, value: any): this;
45
+ /**
46
+ * Add a not-equal filter ($ne)
47
+ */
48
+ ne(field: string, value: any): this;
49
+ /**
50
+ * Add a greater-than filter ($gt)
51
+ */
52
+ gt(field: string, value: any): this;
53
+ /**
54
+ * Add a greater-than-or-equal filter ($gte)
55
+ */
56
+ gte(field: string, value: any): this;
57
+ /**
58
+ * Add a less-than filter ($lt)
59
+ */
60
+ lt(field: string, value: any): this;
61
+ /**
62
+ * Add a less-than-or-equal filter ($lte)
63
+ */
64
+ lte(field: string, value: any): this;
65
+ /**
66
+ * Add an in-array filter ($in)
67
+ */
68
+ in(field: string, values: any[]): this;
69
+ /**
70
+ * Add a not-in-array filter ($nin)
71
+ */
72
+ nin(field: string, values: any[]): this;
73
+ /**
74
+ * Add a contains filter (substring match)
75
+ */
76
+ contains(field: string, substring: string): this;
77
+ /**
78
+ * Add a starts-with filter
79
+ */
80
+ startsWith(field: string, prefix: string): this;
81
+ /**
82
+ * Add an ends-with filter
83
+ */
84
+ endsWith(field: string, suffix: string): this;
85
+ /**
86
+ * Add a regex filter
87
+ */
88
+ regex(field: string, pattern: string): this;
89
+ /**
90
+ * Combine filters with AND logic
91
+ */
92
+ and(conditions: any[]): this;
93
+ /**
94
+ * Combine filters with OR logic
95
+ */
96
+ or(conditions: any[]): this;
97
+ /**
98
+ * Negate a filter
99
+ */
100
+ not(condition: any): this;
101
+ /**
102
+ * Add a raw filter expression
103
+ */
104
+ rawFilter(filter: any): this;
105
+ /**
106
+ * Add a sort field in ascending order
107
+ */
108
+ sortAsc(field: string): this;
109
+ /**
110
+ * Add a sort field in descending order
111
+ */
112
+ sortDesc(field: string): this;
113
+ /**
114
+ * Set the maximum number of results
115
+ */
116
+ limit(limit: number): this;
117
+ /**
118
+ * Set the number of results to skip (for pagination)
119
+ */
120
+ skip(skip: number): this;
121
+ /**
122
+ * Set page number and page size (convenience method)
123
+ */
124
+ page(page: number, pageSize: number): this;
125
+ /**
126
+ * Add a join configuration
127
+ */
128
+ join(joinConfig: any): this;
129
+ /**
130
+ * Bypass cache for this query
131
+ */
132
+ bypassCache(bypass?: boolean): this;
133
+ /**
134
+ * Bypass ripple for this query
135
+ */
136
+ bypassRipple(bypass?: boolean): this;
137
+ /**
138
+ * Build the final Query object
139
+ */
140
+ build(): Query;
141
+ }
@@ -0,0 +1,370 @@
1
+ "use strict";
2
+ /**
3
+ * Query Builder for constructing complex queries with fluent API
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.QueryBuilder = exports.SortOrder = void 0;
7
+ var SortOrder;
8
+ (function (SortOrder) {
9
+ SortOrder["Asc"] = "asc";
10
+ SortOrder["Desc"] = "desc";
11
+ })(SortOrder || (exports.SortOrder = SortOrder = {}));
12
+ /**
13
+ * Fluent API for building complex database queries
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const query = new QueryBuilder()
18
+ * .eq("status", "active")
19
+ * .gt("age", 18)
20
+ * .sortDesc("created_at")
21
+ * .limit(10)
22
+ * .build();
23
+ * ```
24
+ */
25
+ class QueryBuilder {
26
+ constructor() {
27
+ this.filters = [];
28
+ this.sortFields = [];
29
+ this._bypassCache = false;
30
+ this._bypassRipple = false;
31
+ }
32
+ // ========================================================================
33
+ // Comparison Operators
34
+ // ========================================================================
35
+ /**
36
+ * Add an equality filter ($eq)
37
+ */
38
+ eq(field, value) {
39
+ this.filters.push({
40
+ type: "Condition",
41
+ content: {
42
+ field,
43
+ operator: "Eq",
44
+ value,
45
+ },
46
+ });
47
+ return this;
48
+ }
49
+ /**
50
+ * Add a not-equal filter ($ne)
51
+ */
52
+ ne(field, value) {
53
+ this.filters.push({
54
+ type: "Condition",
55
+ content: {
56
+ field,
57
+ operator: "Ne",
58
+ value,
59
+ },
60
+ });
61
+ return this;
62
+ }
63
+ /**
64
+ * Add a greater-than filter ($gt)
65
+ */
66
+ gt(field, value) {
67
+ this.filters.push({
68
+ type: "Condition",
69
+ content: {
70
+ field,
71
+ operator: "Gt",
72
+ value,
73
+ },
74
+ });
75
+ return this;
76
+ }
77
+ /**
78
+ * Add a greater-than-or-equal filter ($gte)
79
+ */
80
+ gte(field, value) {
81
+ this.filters.push({
82
+ type: "Condition",
83
+ content: {
84
+ field,
85
+ operator: "Gte",
86
+ value,
87
+ },
88
+ });
89
+ return this;
90
+ }
91
+ /**
92
+ * Add a less-than filter ($lt)
93
+ */
94
+ lt(field, value) {
95
+ this.filters.push({
96
+ type: "Condition",
97
+ content: {
98
+ field,
99
+ operator: "Lt",
100
+ value,
101
+ },
102
+ });
103
+ return this;
104
+ }
105
+ /**
106
+ * Add a less-than-or-equal filter ($lte)
107
+ */
108
+ lte(field, value) {
109
+ this.filters.push({
110
+ type: "Condition",
111
+ content: {
112
+ field,
113
+ operator: "Lte",
114
+ value,
115
+ },
116
+ });
117
+ return this;
118
+ }
119
+ /**
120
+ * Add an in-array filter ($in)
121
+ */
122
+ in(field, values) {
123
+ this.filters.push({
124
+ type: "Condition",
125
+ content: {
126
+ field,
127
+ operator: "In",
128
+ value: values,
129
+ },
130
+ });
131
+ return this;
132
+ }
133
+ /**
134
+ * Add a not-in-array filter ($nin)
135
+ */
136
+ nin(field, values) {
137
+ this.filters.push({
138
+ type: "Condition",
139
+ content: {
140
+ field,
141
+ operator: "NotIn",
142
+ value: values,
143
+ },
144
+ });
145
+ return this;
146
+ }
147
+ // ========================================================================
148
+ // String Operators
149
+ // ========================================================================
150
+ /**
151
+ * Add a contains filter (substring match)
152
+ */
153
+ contains(field, substring) {
154
+ this.filters.push({
155
+ type: "Condition",
156
+ content: {
157
+ field,
158
+ operator: "Contains",
159
+ value: substring,
160
+ },
161
+ });
162
+ return this;
163
+ }
164
+ /**
165
+ * Add a starts-with filter
166
+ */
167
+ startsWith(field, prefix) {
168
+ this.filters.push({
169
+ type: "Condition",
170
+ content: {
171
+ field,
172
+ operator: "StartsWith",
173
+ value: prefix,
174
+ },
175
+ });
176
+ return this;
177
+ }
178
+ /**
179
+ * Add an ends-with filter
180
+ */
181
+ endsWith(field, suffix) {
182
+ this.filters.push({
183
+ type: "Condition",
184
+ content: {
185
+ field,
186
+ operator: "EndsWith",
187
+ value: suffix,
188
+ },
189
+ });
190
+ return this;
191
+ }
192
+ /**
193
+ * Add a regex filter
194
+ */
195
+ regex(field, pattern) {
196
+ this.filters.push({
197
+ type: "Condition",
198
+ content: {
199
+ field,
200
+ operator: "Regex",
201
+ value: pattern,
202
+ },
203
+ });
204
+ return this;
205
+ }
206
+ // ========================================================================
207
+ // Logical Operators
208
+ // ========================================================================
209
+ /**
210
+ * Combine filters with AND logic
211
+ */
212
+ and(conditions) {
213
+ this.filters.push({
214
+ type: "Logical",
215
+ content: {
216
+ operator: "And",
217
+ expressions: conditions,
218
+ },
219
+ });
220
+ return this;
221
+ }
222
+ /**
223
+ * Combine filters with OR logic
224
+ */
225
+ or(conditions) {
226
+ this.filters.push({
227
+ type: "Logical",
228
+ content: {
229
+ operator: "Or",
230
+ expressions: conditions,
231
+ },
232
+ });
233
+ return this;
234
+ }
235
+ /**
236
+ * Negate a filter
237
+ */
238
+ not(condition) {
239
+ this.filters.push({
240
+ type: "Logical",
241
+ content: {
242
+ operator: "Not",
243
+ expressions: [condition],
244
+ },
245
+ });
246
+ return this;
247
+ }
248
+ /**
249
+ * Add a raw filter expression
250
+ */
251
+ rawFilter(filter) {
252
+ this.filters.push(filter);
253
+ return this;
254
+ }
255
+ // ========================================================================
256
+ // Sorting
257
+ // ========================================================================
258
+ /**
259
+ * Add a sort field in ascending order
260
+ */
261
+ sortAsc(field) {
262
+ this.sortFields.push({ field, order: SortOrder.Asc });
263
+ return this;
264
+ }
265
+ /**
266
+ * Add a sort field in descending order
267
+ */
268
+ sortDesc(field) {
269
+ this.sortFields.push({ field, order: SortOrder.Desc });
270
+ return this;
271
+ }
272
+ // ========================================================================
273
+ // Pagination
274
+ // ========================================================================
275
+ /**
276
+ * Set the maximum number of results
277
+ */
278
+ limit(limit) {
279
+ this._limit = limit;
280
+ return this;
281
+ }
282
+ /**
283
+ * Set the number of results to skip (for pagination)
284
+ */
285
+ skip(skip) {
286
+ this._skip = skip;
287
+ return this;
288
+ }
289
+ /**
290
+ * Set page number and page size (convenience method)
291
+ */
292
+ page(page, pageSize) {
293
+ this._skip = page * pageSize;
294
+ this._limit = pageSize;
295
+ return this;
296
+ }
297
+ // ========================================================================
298
+ // Joins
299
+ // ========================================================================
300
+ /**
301
+ * Add a join configuration
302
+ */
303
+ join(joinConfig) {
304
+ this._join = joinConfig;
305
+ return this;
306
+ }
307
+ // ========================================================================
308
+ // Performance Flags
309
+ // ========================================================================
310
+ /**
311
+ * Bypass cache for this query
312
+ */
313
+ bypassCache(bypass = true) {
314
+ this._bypassCache = bypass;
315
+ return this;
316
+ }
317
+ /**
318
+ * Bypass ripple for this query
319
+ */
320
+ bypassRipple(bypass = true) {
321
+ this._bypassRipple = bypass;
322
+ return this;
323
+ }
324
+ // ========================================================================
325
+ // Build
326
+ // ========================================================================
327
+ /**
328
+ * Build the final Query object
329
+ */
330
+ build() {
331
+ const query = {};
332
+ // Combine all filters with AND logic if multiple filters exist
333
+ if (this.filters.length > 0) {
334
+ query.filter =
335
+ this.filters.length === 1
336
+ ? this.filters[0]
337
+ : {
338
+ type: "Logical",
339
+ content: {
340
+ operator: "And",
341
+ expressions: this.filters,
342
+ },
343
+ };
344
+ }
345
+ // Build sort expression
346
+ if (this.sortFields.length > 0) {
347
+ query.sort = this.sortFields.map(({ field, order }) => ({
348
+ field,
349
+ ascending: order === SortOrder.Asc,
350
+ }));
351
+ }
352
+ if (this._limit !== undefined) {
353
+ query.limit = this._limit;
354
+ }
355
+ if (this._skip !== undefined) {
356
+ query.skip = this._skip;
357
+ }
358
+ if (this._join !== undefined) {
359
+ query.join = this._join;
360
+ }
361
+ if (this._bypassCache) {
362
+ query.bypass_cache = true;
363
+ }
364
+ if (this._bypassRipple) {
365
+ query.bypass_ripple = true;
366
+ }
367
+ return query;
368
+ }
369
+ }
370
+ exports.QueryBuilder = QueryBuilder;