@onchaindb/sdk 0.0.6

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.
Files changed (66) hide show
  1. package/README.md +475 -0
  2. package/dist/batch.d.ts +42 -0
  3. package/dist/batch.d.ts.map +1 -0
  4. package/dist/batch.js +124 -0
  5. package/dist/batch.js.map +1 -0
  6. package/dist/client.d.ts +93 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +679 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/database.d.ts +194 -0
  11. package/dist/database.d.ts.map +1 -0
  12. package/dist/database.js +211 -0
  13. package/dist/database.js.map +1 -0
  14. package/dist/index.d.ts +15 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +37 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/query-sdk/ConditionBuilder.d.ts +23 -0
  19. package/dist/query-sdk/ConditionBuilder.d.ts.map +1 -0
  20. package/dist/query-sdk/ConditionBuilder.js +76 -0
  21. package/dist/query-sdk/ConditionBuilder.js.map +1 -0
  22. package/dist/query-sdk/FieldConditionBuilder.d.ts +2 -0
  23. package/dist/query-sdk/FieldConditionBuilder.d.ts.map +1 -0
  24. package/dist/query-sdk/FieldConditionBuilder.js +6 -0
  25. package/dist/query-sdk/FieldConditionBuilder.js.map +1 -0
  26. package/dist/query-sdk/NestedBuilders.d.ts +44 -0
  27. package/dist/query-sdk/NestedBuilders.d.ts.map +1 -0
  28. package/dist/query-sdk/NestedBuilders.js +131 -0
  29. package/dist/query-sdk/NestedBuilders.js.map +1 -0
  30. package/dist/query-sdk/OnChainDB.d.ts +27 -0
  31. package/dist/query-sdk/OnChainDB.d.ts.map +1 -0
  32. package/dist/query-sdk/OnChainDB.js +191 -0
  33. package/dist/query-sdk/OnChainDB.js.map +1 -0
  34. package/dist/query-sdk/PrismaLikeClient.d.ts +41 -0
  35. package/dist/query-sdk/PrismaLikeClient.d.ts.map +1 -0
  36. package/dist/query-sdk/PrismaLikeClient.js +202 -0
  37. package/dist/query-sdk/PrismaLikeClient.js.map +1 -0
  38. package/dist/query-sdk/QueryBuilder.d.ts +155 -0
  39. package/dist/query-sdk/QueryBuilder.d.ts.map +1 -0
  40. package/dist/query-sdk/QueryBuilder.js +757 -0
  41. package/dist/query-sdk/QueryBuilder.js.map +1 -0
  42. package/dist/query-sdk/QueryResult.d.ts +53 -0
  43. package/dist/query-sdk/QueryResult.d.ts.map +1 -0
  44. package/dist/query-sdk/QueryResult.js +267 -0
  45. package/dist/query-sdk/QueryResult.js.map +1 -0
  46. package/dist/query-sdk/SelectionBuilder.d.ts +21 -0
  47. package/dist/query-sdk/SelectionBuilder.d.ts.map +1 -0
  48. package/dist/query-sdk/SelectionBuilder.js +67 -0
  49. package/dist/query-sdk/SelectionBuilder.js.map +1 -0
  50. package/dist/query-sdk/adapters/HttpClientAdapter.d.ts +28 -0
  51. package/dist/query-sdk/adapters/HttpClientAdapter.d.ts.map +1 -0
  52. package/dist/query-sdk/adapters/HttpClientAdapter.js +206 -0
  53. package/dist/query-sdk/adapters/HttpClientAdapter.js.map +1 -0
  54. package/dist/query-sdk/index.d.ts +38 -0
  55. package/dist/query-sdk/index.d.ts.map +1 -0
  56. package/dist/query-sdk/index.js +28 -0
  57. package/dist/query-sdk/index.js.map +1 -0
  58. package/dist/query-sdk/operators.d.ts +57 -0
  59. package/dist/query-sdk/operators.d.ts.map +1 -0
  60. package/dist/query-sdk/operators.js +275 -0
  61. package/dist/query-sdk/operators.js.map +1 -0
  62. package/dist/types.d.ts +263 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +46 -0
  65. package/dist/types.js.map +1 -0
  66. package/package.json +47 -0
@@ -0,0 +1,757 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GroupByQueryBuilder = exports.JoinWhereClause = exports.JoinBuilder = exports.WhereClause = exports.QueryBuilder = void 0;
4
+ const operators_1 = require("./operators");
5
+ const SelectionBuilder_1 = require("./SelectionBuilder");
6
+ const ConditionBuilder_1 = require("./ConditionBuilder");
7
+ class QueryBuilder {
8
+ constructor(httpClient, serverUrl, app) {
9
+ this.serverJoinConfigs = [];
10
+ this.joinConfigs = [];
11
+ this.httpClient = httpClient;
12
+ this.serverUrl = serverUrl;
13
+ this.app = app;
14
+ }
15
+ static new(httpClient, serverUrl, app) {
16
+ return new QueryBuilder(httpClient, serverUrl, app);
17
+ }
18
+ withHttpClient(httpClient) {
19
+ this.httpClient = httpClient;
20
+ return this;
21
+ }
22
+ withServerUrl(serverUrl) {
23
+ this.serverUrl = serverUrl;
24
+ return this;
25
+ }
26
+ find(builderFn) {
27
+ const conditionBuilder = new ConditionBuilder_1.ConditionBuilder();
28
+ this.findConditions = builderFn(conditionBuilder);
29
+ return this;
30
+ }
31
+ collection(s) {
32
+ this.collectionName = s;
33
+ return this;
34
+ }
35
+ whereField(fieldName) {
36
+ return new WhereClause(this, fieldName);
37
+ }
38
+ serverJoin(alias, model, resolve) {
39
+ this.serverJoinConfigs.push({
40
+ alias,
41
+ model,
42
+ resolve
43
+ });
44
+ return this;
45
+ }
46
+ joinWith(alias, model) {
47
+ return new JoinBuilder(this, alias, model);
48
+ }
49
+ joinOne(alias, model) {
50
+ return new JoinBuilder(this, alias, model, false);
51
+ }
52
+ joinMany(alias, model) {
53
+ return new JoinBuilder(this, alias, model, true);
54
+ }
55
+ join(parentCollection, parentField, childField, alias) {
56
+ console.warn('QueryBuilder.join() is deprecated. Use serverJoin(), joinOne(), or joinMany() for server-side JOINs.');
57
+ this.joinConfigs.push({
58
+ parentCollection,
59
+ parentField,
60
+ childField,
61
+ alias
62
+ });
63
+ return this;
64
+ }
65
+ select(builderFn) {
66
+ const selectionBuilder = new SelectionBuilder_1.SelectionBuilder();
67
+ builderFn(selectionBuilder);
68
+ this.selections = selectionBuilder.build();
69
+ return this;
70
+ }
71
+ selectFields(fields) {
72
+ const selectionBuilder = new SelectionBuilder_1.SelectionBuilder();
73
+ selectionBuilder.fields(fields);
74
+ this.selections = selectionBuilder.build();
75
+ return this;
76
+ }
77
+ selectAll() {
78
+ this.selections = SelectionBuilder_1.SelectionBuilder.all();
79
+ return this;
80
+ }
81
+ withFieldMap(fieldMap) {
82
+ this.fieldMap = fieldMap;
83
+ return this;
84
+ }
85
+ limit(limit) {
86
+ this.limitValue = limit;
87
+ return this;
88
+ }
89
+ offset(offset) {
90
+ this.offsetValue = offset;
91
+ return this;
92
+ }
93
+ orderBy(fields) {
94
+ this.sortBy = fields;
95
+ return this;
96
+ }
97
+ includeHistory(include = true) {
98
+ this.includeHistoryValue = include;
99
+ return this;
100
+ }
101
+ async execute() {
102
+ if (!this.httpClient) {
103
+ throw new Error('HTTP client is required for query execution');
104
+ }
105
+ if (!this.serverUrl) {
106
+ throw new Error('Server URL is required for query execution');
107
+ }
108
+ if (this.serverJoinConfigs.length > 0) {
109
+ return this.executeSimpleQuery();
110
+ }
111
+ if (this.joinConfigs.length > 0) {
112
+ console.warn('Using deprecated client-side JOINs. Consider migrating to serverJoin() for better performance.');
113
+ return this.executeWithJoins();
114
+ }
115
+ return this.executeSimpleQuery();
116
+ }
117
+ async executeUnique() {
118
+ const response = await this.execute();
119
+ if (!response.records || response.records.length === 0) {
120
+ return null;
121
+ }
122
+ const sortedRecords = [...response.records].sort((a, b) => {
123
+ const getTimestamp = (record) => {
124
+ return record.updatedAt || record.updated_at ||
125
+ record.createdAt || record.created_at || null;
126
+ };
127
+ const tsA = getTimestamp(a);
128
+ const tsB = getTimestamp(b);
129
+ if (tsB && tsA)
130
+ return tsB.localeCompare(tsA);
131
+ if (tsB && !tsA)
132
+ return -1;
133
+ if (!tsB && tsA)
134
+ return 1;
135
+ return 0;
136
+ });
137
+ return sortedRecords[0];
138
+ }
139
+ async count() {
140
+ const response = await this.execute();
141
+ return response.records?.length || 0;
142
+ }
143
+ async sumBy(field) {
144
+ const response = await this.execute();
145
+ if (!response.records)
146
+ return 0;
147
+ return response.records.reduce((sum, record) => {
148
+ const value = record[field];
149
+ return sum + (typeof value === 'number' ? value : 0);
150
+ }, 0);
151
+ }
152
+ async avgBy(field) {
153
+ const response = await this.execute();
154
+ if (!response.records || response.records.length === 0)
155
+ return 0;
156
+ const sum = response.records.reduce((total, record) => {
157
+ const value = record[field];
158
+ return total + (typeof value === 'number' ? value : 0);
159
+ }, 0);
160
+ return sum / response.records.length;
161
+ }
162
+ async maxBy(field) {
163
+ const response = await this.execute();
164
+ if (!response.records || response.records.length === 0)
165
+ return null;
166
+ return response.records.reduce((max, record) => {
167
+ const value = record[field];
168
+ if (max === null)
169
+ return value;
170
+ return value > max ? value : max;
171
+ }, null);
172
+ }
173
+ async minBy(field) {
174
+ const response = await this.execute();
175
+ if (!response.records || response.records.length === 0)
176
+ return null;
177
+ return response.records.reduce((min, record) => {
178
+ const value = record[field];
179
+ if (min === null)
180
+ return value;
181
+ return value < min ? value : min;
182
+ }, null);
183
+ }
184
+ async distinctBy(field) {
185
+ const response = await this.execute();
186
+ if (!response.records)
187
+ return [];
188
+ const uniqueValues = new Set();
189
+ for (const record of response.records) {
190
+ const value = record[field];
191
+ if (value !== undefined && value !== null) {
192
+ uniqueValues.add(value);
193
+ }
194
+ }
195
+ return Array.from(uniqueValues);
196
+ }
197
+ async countDistinct(field) {
198
+ const distinctValues = await this.distinctBy(field);
199
+ return distinctValues.length;
200
+ }
201
+ groupBy(field) {
202
+ return new GroupByQueryBuilder(this, field);
203
+ }
204
+ async executeWithPayment(quoteId, paymentProof, network) {
205
+ if (!this.httpClient) {
206
+ throw new Error('HTTP client is required for query execution');
207
+ }
208
+ if (!this.serverUrl) {
209
+ throw new Error('Server URL is required for query execution');
210
+ }
211
+ const x402Payload = {
212
+ x402Version: 1,
213
+ scheme: network?.includes('sepolia') || network?.includes('ethereum') ? 'ethereum-native' : 'celestia-native',
214
+ network: network || 'mocha-4',
215
+ quoteId: quoteId,
216
+ payload: {
217
+ txHash: paymentProof.toLowerCase(),
218
+ sender: 'unknown',
219
+ timestamp: Math.floor(Date.now() / 1000)
220
+ }
221
+ };
222
+ const encodedPayment = Buffer.from(JSON.stringify(x402Payload)).toString('base64');
223
+ const request = this.getQueryRequest();
224
+ try {
225
+ const response = await this.httpClient.post(`${this.serverUrl}/list`, request, {
226
+ 'Content-Type': 'application/json',
227
+ 'X-PAYMENT': encodedPayment
228
+ });
229
+ if (response?.headers && response.headers['x-payment-response']) {
230
+ console.log('✅ Payment confirmed:', JSON.parse(response.headers['x-payment-response']));
231
+ }
232
+ return response?.data || {
233
+ records: [],
234
+ total: 0,
235
+ page: 0,
236
+ limit: 0
237
+ };
238
+ }
239
+ catch (error) {
240
+ throw new Error(`Paid query execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
241
+ }
242
+ }
243
+ getQueryRequest() {
244
+ const queryValue = this.buildQueryValue();
245
+ return {
246
+ ...queryValue,
247
+ limit: this.limitValue,
248
+ offset: this.offsetValue,
249
+ sortBy: this.sortBy,
250
+ root: `${this.app}::${this.collectionName}`
251
+ };
252
+ }
253
+ isValid() {
254
+ return this.findConditions !== undefined || this.selections !== undefined;
255
+ }
256
+ buildRawQuery() {
257
+ return {
258
+ ...this.buildQueryValue(),
259
+ limit: this.limitValue,
260
+ offset: this.offsetValue,
261
+ sortBy: this.sortBy
262
+ };
263
+ }
264
+ clone() {
265
+ const cloned = new QueryBuilder(this.httpClient, this.serverUrl, this.app);
266
+ cloned.findConditions = this.findConditions;
267
+ cloned.selections = this.selections ? { ...this.selections } : undefined;
268
+ cloned.fieldMap = this.fieldMap ? { ...this.fieldMap } : undefined;
269
+ cloned.limitValue = this.limitValue;
270
+ cloned.offsetValue = this.offsetValue;
271
+ cloned.sortBy = this.sortBy;
272
+ cloned.includeHistoryValue = this.includeHistoryValue;
273
+ cloned.collectionName = this.collectionName;
274
+ cloned.serverJoinConfigs = [...this.serverJoinConfigs];
275
+ cloned.joinConfigs = [...this.joinConfigs];
276
+ return cloned;
277
+ }
278
+ _addServerJoin(config) {
279
+ this.serverJoinConfigs.push(config);
280
+ }
281
+ async executeSimpleQuery() {
282
+ const request = this.getQueryRequest();
283
+ try {
284
+ const response = await this.httpClient.post(`${this.serverUrl}/list`, request, { 'Content-Type': 'application/json' });
285
+ if (response?.status === 402 && response?.data) {
286
+ console.log('💰 Received 402 Payment Required, converting x402 to quote');
287
+ const x402Response = response.data;
288
+ const requirement = x402Response.accepts?.[0];
289
+ if (requirement) {
290
+ const quote = {
291
+ type: 'quote',
292
+ quote_id: requirement.quoteId,
293
+ matched_records: parseInt(requirement.description?.match(/(\d+) records/)?.[1] || '0'),
294
+ billable_fields: requirement.description?.match(/fields: (.*)/)?.[1]?.split(', ') || [],
295
+ cost_breakdown: requirement.costBreakdown || {},
296
+ total_cost_tia: parseInt(requirement.maxAmountRequired) / 1000000,
297
+ broker_address: requirement.payTo,
298
+ expires_at: requirement.expiresAt
299
+ };
300
+ console.log('✅ Converted x402 to quote:', quote);
301
+ return quote;
302
+ }
303
+ }
304
+ if (response?.data && response.data.type === 'quote') {
305
+ return response.data;
306
+ }
307
+ return response?.data || {
308
+ records: [],
309
+ limit: 0,
310
+ page: 0,
311
+ total: 0,
312
+ };
313
+ }
314
+ catch (error) {
315
+ const response = error?.response;
316
+ if (response?.status === 402 && response?.data) {
317
+ const x402Response = response.data;
318
+ const requirement = x402Response.accepts?.[0];
319
+ if (requirement) {
320
+ const quote = {
321
+ type: 'quote',
322
+ quote_id: requirement.quoteId,
323
+ matched_records: parseInt(requirement.description?.match(/(\d+) records/)?.[1] || '0'),
324
+ billable_fields: requirement.description?.match(/fields: (.*)/)?.[1]?.split(', ') || [],
325
+ cost_breakdown: requirement.costBreakdown || {},
326
+ total_cost_tia: parseInt(requirement.maxAmountRequired) / 1000000,
327
+ broker_address: requirement.payTo,
328
+ expires_at: requirement.expiresAt
329
+ };
330
+ return quote;
331
+ }
332
+ }
333
+ throw new Error(`Query execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
334
+ }
335
+ }
336
+ async executeWithJoins() {
337
+ const mainQuery = this.clone();
338
+ mainQuery.joinConfigs = [];
339
+ const mainResults = await mainQuery.executeSimpleQuery();
340
+ if (mainResults.records.length === 0) {
341
+ return mainResults;
342
+ }
343
+ const joinResults = {};
344
+ for (const joinConfig of this.joinConfigs) {
345
+ const joinKeys = [...new Set(mainResults.records
346
+ .map(record => record[joinConfig.childField])
347
+ .filter(key => key !== null && key !== undefined))];
348
+ if (joinKeys.length > 0) {
349
+ const joinQuery = new QueryBuilder(this.httpClient, this.serverUrl, this.app);
350
+ const joinResponse = await joinQuery
351
+ .collection(joinConfig.parentCollection)
352
+ .whereField(joinConfig.parentField).in(joinKeys)
353
+ .selectAll()
354
+ .executeSimpleQuery();
355
+ joinResults[joinConfig.alias] = joinResponse.records;
356
+ }
357
+ else {
358
+ joinResults[joinConfig.alias] = [];
359
+ }
360
+ }
361
+ const mergedRecords = mainResults.records.map(mainRecord => {
362
+ const merged = { ...mainRecord };
363
+ for (const joinConfig of this.joinConfigs) {
364
+ const joinKey = mainRecord[joinConfig.childField];
365
+ const relatedRecords = joinResults[joinConfig.alias].filter(joinRecord => joinRecord[joinConfig.parentField] === joinKey);
366
+ if (joinConfig.parentCollection === this.collectionName) {
367
+ merged[joinConfig.alias] = relatedRecords;
368
+ }
369
+ else {
370
+ merged[joinConfig.alias] = relatedRecords.length > 0 ? relatedRecords[0] : null;
371
+ }
372
+ }
373
+ return merged;
374
+ });
375
+ return {
376
+ records: mergedRecords,
377
+ limit: mainResults.limit,
378
+ page: mainResults.page,
379
+ total: mainResults.total
380
+ };
381
+ }
382
+ buildQueryValue() {
383
+ let find = this.findConditions ? this.findConditions.toComposable() : {};
384
+ const select = this.selections || SelectionBuilder_1.SelectionBuilder.all();
385
+ if (this.serverJoinConfigs.length > 0) {
386
+ for (const join of this.serverJoinConfigs) {
387
+ const joinConfig = {
388
+ resolve: join.resolve,
389
+ model: join.model
390
+ };
391
+ if (join.many !== undefined) {
392
+ joinConfig.many = join.many;
393
+ }
394
+ find[join.alias] = joinConfig;
395
+ }
396
+ }
397
+ const queryValue = {
398
+ find,
399
+ select
400
+ };
401
+ if (this.includeHistoryValue !== undefined) {
402
+ queryValue.include_history = this.includeHistoryValue;
403
+ }
404
+ return queryValue;
405
+ }
406
+ }
407
+ exports.QueryBuilder = QueryBuilder;
408
+ class WhereClause {
409
+ constructor(queryBuilder, fieldName) {
410
+ this.queryBuilder = queryBuilder;
411
+ this.fieldName = fieldName;
412
+ }
413
+ equals(value) {
414
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).equals(value);
415
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
416
+ return this.queryBuilder;
417
+ }
418
+ notEquals(value) {
419
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).notEquals(value);
420
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
421
+ return this.queryBuilder;
422
+ }
423
+ greaterThan(value) {
424
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).greaterThan(value);
425
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
426
+ return this.queryBuilder;
427
+ }
428
+ greaterThanOrEqual(value) {
429
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).greaterThanOrEqual(value);
430
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
431
+ return this.queryBuilder;
432
+ }
433
+ lessThan(value) {
434
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).lessThan(value);
435
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
436
+ return this.queryBuilder;
437
+ }
438
+ lessThanOrEqual(value) {
439
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).lessThanOrEqual(value);
440
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
441
+ return this.queryBuilder;
442
+ }
443
+ contains(value) {
444
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).contains(value);
445
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
446
+ return this.queryBuilder;
447
+ }
448
+ startsWith(value) {
449
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).startsWith(value);
450
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
451
+ return this.queryBuilder;
452
+ }
453
+ endsWith(value) {
454
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).endsWith(value);
455
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
456
+ return this.queryBuilder;
457
+ }
458
+ in(values) {
459
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).in(values);
460
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
461
+ return this.queryBuilder;
462
+ }
463
+ notIn(values) {
464
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).notIn(values);
465
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
466
+ return this.queryBuilder;
467
+ }
468
+ exists() {
469
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).exists();
470
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
471
+ return this.queryBuilder;
472
+ }
473
+ notExists() {
474
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).notExists();
475
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
476
+ return this.queryBuilder;
477
+ }
478
+ isNull() {
479
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).isNull();
480
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
481
+ return this.queryBuilder;
482
+ }
483
+ isNotNull() {
484
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).isNotNull();
485
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
486
+ return this.queryBuilder;
487
+ }
488
+ regExpMatches(pattern) {
489
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).regExpMatches(pattern);
490
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
491
+ return this.queryBuilder;
492
+ }
493
+ includesCaseInsensitive(value) {
494
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).includesCaseInsensitive(value);
495
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
496
+ return this.queryBuilder;
497
+ }
498
+ startsWithCaseInsensitive(value) {
499
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).startsWithCaseInsensitive(value);
500
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
501
+ return this.queryBuilder;
502
+ }
503
+ endsWithCaseInsensitive(value) {
504
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).endsWithCaseInsensitive(value);
505
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
506
+ return this.queryBuilder;
507
+ }
508
+ isLocalIp() {
509
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).isLocalIp();
510
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
511
+ return this.queryBuilder;
512
+ }
513
+ isExternalIp() {
514
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).isExternalIp();
515
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
516
+ return this.queryBuilder;
517
+ }
518
+ b64(value) {
519
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).b64(value);
520
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
521
+ return this.queryBuilder;
522
+ }
523
+ inDataset(dataset) {
524
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).inDataset(dataset);
525
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
526
+ return this.queryBuilder;
527
+ }
528
+ inCountry(countryCode) {
529
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).inCountry(countryCode);
530
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
531
+ return this.queryBuilder;
532
+ }
533
+ cidr(cidr) {
534
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).cidr(cidr);
535
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
536
+ return this.queryBuilder;
537
+ }
538
+ between(min, max) {
539
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).between(min, max);
540
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
541
+ return this.queryBuilder;
542
+ }
543
+ isTrue() {
544
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).isTrue();
545
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
546
+ return this.queryBuilder;
547
+ }
548
+ isFalse() {
549
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).isFalse();
550
+ this.queryBuilder.findConditions = operators_1.LogicalOperator.Condition(condition);
551
+ return this.queryBuilder;
552
+ }
553
+ }
554
+ exports.WhereClause = WhereClause;
555
+ class JoinBuilder {
556
+ constructor(parentBuilder, alias, model, many) {
557
+ this.findConditions = {};
558
+ this.nestedJoins = [];
559
+ this.parentBuilder = parentBuilder;
560
+ this.alias = alias;
561
+ this.model = model;
562
+ this.many = many;
563
+ }
564
+ on(builderFn) {
565
+ const conditionBuilder = new ConditionBuilder_1.ConditionBuilder();
566
+ this.findConditions = builderFn(conditionBuilder).toComposable();
567
+ return this;
568
+ }
569
+ onField(fieldName) {
570
+ return new JoinWhereClause(this, fieldName);
571
+ }
572
+ selecting(builderFn) {
573
+ const selectionBuilder = new SelectionBuilder_1.SelectionBuilder();
574
+ builderFn(selectionBuilder);
575
+ this.selections = selectionBuilder.build();
576
+ return this;
577
+ }
578
+ selectFields(fields) {
579
+ const selectionBuilder = new SelectionBuilder_1.SelectionBuilder();
580
+ selectionBuilder.fields(fields);
581
+ this.selections = selectionBuilder.build();
582
+ return this;
583
+ }
584
+ selectAll() {
585
+ this.selections = SelectionBuilder_1.SelectionBuilder.all();
586
+ return this;
587
+ }
588
+ joinOne(alias, model) {
589
+ return new JoinBuilder(this, alias, model, false);
590
+ }
591
+ joinMany(alias, model) {
592
+ return new JoinBuilder(this, alias, model, true);
593
+ }
594
+ build() {
595
+ const joinConfig = {
596
+ alias: this.alias,
597
+ model: this.model,
598
+ many: this.many,
599
+ resolve: {
600
+ find: this.buildFindWithNestedJoins(),
601
+ select: this.selections || SelectionBuilder_1.SelectionBuilder.all()
602
+ }
603
+ };
604
+ this.parentBuilder._addServerJoin(joinConfig);
605
+ return this.parentBuilder;
606
+ }
607
+ buildFindWithNestedJoins() {
608
+ const find = Object.keys(this.findConditions).length > 0 ? { ...this.findConditions } : {};
609
+ if (this.nestedJoins.length > 0) {
610
+ for (const nestedJoin of this.nestedJoins) {
611
+ const joinConfig = {
612
+ resolve: nestedJoin.resolve,
613
+ model: nestedJoin.model
614
+ };
615
+ if (nestedJoin.many !== undefined) {
616
+ joinConfig.many = nestedJoin.many;
617
+ }
618
+ find[nestedJoin.alias] = joinConfig;
619
+ }
620
+ }
621
+ return Object.keys(find).length > 0 ? find : undefined;
622
+ }
623
+ _setFindConditions(conditions) {
624
+ this.findConditions = conditions;
625
+ }
626
+ _addServerJoin(config) {
627
+ this.nestedJoins.push(config);
628
+ }
629
+ }
630
+ exports.JoinBuilder = JoinBuilder;
631
+ class JoinWhereClause {
632
+ constructor(joinBuilder, fieldName) {
633
+ this.joinBuilder = joinBuilder;
634
+ this.fieldName = fieldName;
635
+ }
636
+ equals(value) {
637
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).equals(value);
638
+ this.joinBuilder._setFindConditions(operators_1.LogicalOperator.Condition(condition).toComposable());
639
+ return this.joinBuilder;
640
+ }
641
+ in(values) {
642
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).in(values);
643
+ this.joinBuilder._setFindConditions(operators_1.LogicalOperator.Condition(condition).toComposable());
644
+ return this.joinBuilder;
645
+ }
646
+ greaterThan(value) {
647
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).greaterThan(value);
648
+ this.joinBuilder._setFindConditions(operators_1.LogicalOperator.Condition(condition).toComposable());
649
+ return this.joinBuilder;
650
+ }
651
+ lessThan(value) {
652
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).lessThan(value);
653
+ this.joinBuilder._setFindConditions(operators_1.LogicalOperator.Condition(condition).toComposable());
654
+ return this.joinBuilder;
655
+ }
656
+ isNull() {
657
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).isNull();
658
+ this.joinBuilder._setFindConditions(operators_1.LogicalOperator.Condition(condition).toComposable());
659
+ return this.joinBuilder;
660
+ }
661
+ isNotNull() {
662
+ const condition = new operators_1.FieldConditionBuilder(this.fieldName).isNotNull();
663
+ this.joinBuilder._setFindConditions(operators_1.LogicalOperator.Condition(condition).toComposable());
664
+ return this.joinBuilder;
665
+ }
666
+ }
667
+ exports.JoinWhereClause = JoinWhereClause;
668
+ class GroupByQueryBuilder {
669
+ constructor(queryBuilder, groupByField) {
670
+ this.queryBuilder = queryBuilder;
671
+ this.groupByField = groupByField;
672
+ }
673
+ async count() {
674
+ const response = await this.queryBuilder.execute();
675
+ if (!response.records)
676
+ return {};
677
+ const groups = {};
678
+ for (const record of response.records) {
679
+ const key = this.getGroupKey(record);
680
+ groups[key] = (groups[key] || 0) + 1;
681
+ }
682
+ return groups;
683
+ }
684
+ async sumBy(field) {
685
+ const response = await this.queryBuilder.execute();
686
+ if (!response.records)
687
+ return {};
688
+ const groups = {};
689
+ for (const record of response.records) {
690
+ const key = this.getGroupKey(record);
691
+ const value = record[field];
692
+ groups[key] = (groups[key] || 0) + (typeof value === 'number' ? value : 0);
693
+ }
694
+ return groups;
695
+ }
696
+ async avgBy(field) {
697
+ const response = await this.queryBuilder.execute();
698
+ if (!response.records)
699
+ return {};
700
+ const groups = {};
701
+ for (const record of response.records) {
702
+ const key = this.getGroupKey(record);
703
+ const value = record[field];
704
+ if (!groups[key]) {
705
+ groups[key] = { sum: 0, count: 0 };
706
+ }
707
+ groups[key].sum += typeof value === 'number' ? value : 0;
708
+ groups[key].count += 1;
709
+ }
710
+ const result = {};
711
+ for (const [key, { sum, count }] of Object.entries(groups)) {
712
+ result[key] = count > 0 ? sum / count : 0;
713
+ }
714
+ return result;
715
+ }
716
+ async maxBy(field) {
717
+ const response = await this.queryBuilder.execute();
718
+ if (!response.records)
719
+ return {};
720
+ const groups = {};
721
+ for (const record of response.records) {
722
+ const key = this.getGroupKey(record);
723
+ const value = record[field];
724
+ if (!(key in groups) || value > groups[key]) {
725
+ groups[key] = value;
726
+ }
727
+ }
728
+ return groups;
729
+ }
730
+ async minBy(field) {
731
+ const response = await this.queryBuilder.execute();
732
+ if (!response.records)
733
+ return {};
734
+ const groups = {};
735
+ for (const record of response.records) {
736
+ const key = this.getGroupKey(record);
737
+ const value = record[field];
738
+ if (!(key in groups) || value < groups[key]) {
739
+ groups[key] = value;
740
+ }
741
+ }
742
+ return groups;
743
+ }
744
+ getGroupKey(record) {
745
+ if (this.groupByField.includes('.')) {
746
+ const parts = this.groupByField.split('.');
747
+ let current = record;
748
+ for (const part of parts) {
749
+ current = current?.[part];
750
+ }
751
+ return String(current ?? 'null');
752
+ }
753
+ return String(record[this.groupByField] ?? 'null');
754
+ }
755
+ }
756
+ exports.GroupByQueryBuilder = GroupByQueryBuilder;
757
+ //# sourceMappingURL=QueryBuilder.js.map