@inkress/admin-sdk 1.0.0 → 1.1.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +213 -0
  2. package/README.md +1174 -87
  3. package/dist/client.d.ts +3 -3
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/data-mappings.d.ts +177 -0
  6. package/dist/data-mappings.d.ts.map +1 -0
  7. package/dist/index.d.ts +34 -4
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.esm.js +4151 -154
  10. package/dist/index.esm.js.map +1 -1
  11. package/dist/index.js +4188 -153
  12. package/dist/index.js.map +1 -1
  13. package/dist/resources/addresses.d.ts +58 -0
  14. package/dist/resources/addresses.d.ts.map +1 -0
  15. package/dist/resources/billing-plans.d.ts +32 -15
  16. package/dist/resources/billing-plans.d.ts.map +1 -1
  17. package/dist/resources/categories.d.ts +30 -20
  18. package/dist/resources/categories.d.ts.map +1 -1
  19. package/dist/resources/currencies.d.ts +41 -0
  20. package/dist/resources/currencies.d.ts.map +1 -0
  21. package/dist/resources/exchange-rates.d.ts +50 -0
  22. package/dist/resources/exchange-rates.d.ts.map +1 -0
  23. package/dist/resources/fees.d.ts +58 -0
  24. package/dist/resources/fees.d.ts.map +1 -0
  25. package/dist/resources/financial-accounts.d.ts +47 -0
  26. package/dist/resources/financial-accounts.d.ts.map +1 -0
  27. package/dist/resources/financial-requests.d.ts +51 -0
  28. package/dist/resources/financial-requests.d.ts.map +1 -0
  29. package/dist/resources/generics.d.ts +57 -0
  30. package/dist/resources/generics.d.ts.map +1 -0
  31. package/dist/resources/kyc.d.ts +118 -0
  32. package/dist/resources/kyc.d.ts.map +1 -0
  33. package/dist/resources/merchants.d.ts +52 -15
  34. package/dist/resources/merchants.d.ts.map +1 -1
  35. package/dist/resources/orders.d.ts +74 -28
  36. package/dist/resources/orders.d.ts.map +1 -1
  37. package/dist/resources/payment-links.d.ts +65 -0
  38. package/dist/resources/payment-links.d.ts.map +1 -0
  39. package/dist/resources/payment-methods.d.ts +48 -0
  40. package/dist/resources/payment-methods.d.ts.map +1 -0
  41. package/dist/resources/products.d.ts +62 -16
  42. package/dist/resources/products.d.ts.map +1 -1
  43. package/dist/resources/public.d.ts +33 -7
  44. package/dist/resources/public.d.ts.map +1 -1
  45. package/dist/resources/subscriptions.d.ts +69 -25
  46. package/dist/resources/subscriptions.d.ts.map +1 -1
  47. package/dist/resources/tokens.d.ts +62 -0
  48. package/dist/resources/tokens.d.ts.map +1 -0
  49. package/dist/resources/transaction-entries.d.ts +48 -0
  50. package/dist/resources/transaction-entries.d.ts.map +1 -0
  51. package/dist/resources/users.d.ts +43 -21
  52. package/dist/resources/users.d.ts.map +1 -1
  53. package/dist/resources/webhook-urls.d.ts +49 -0
  54. package/dist/resources/webhook-urls.d.ts.map +1 -0
  55. package/dist/types/resources.d.ts +1294 -0
  56. package/dist/types/resources.d.ts.map +1 -0
  57. package/dist/types.d.ts +1260 -183
  58. package/dist/types.d.ts.map +1 -1
  59. package/dist/utils/query-builders.d.ts +518 -0
  60. package/dist/utils/query-builders.d.ts.map +1 -0
  61. package/dist/utils/query-transformer.d.ts +123 -0
  62. package/dist/utils/query-transformer.d.ts.map +1 -0
  63. package/dist/utils/translators.d.ts +126 -0
  64. package/dist/utils/translators.d.ts.map +1 -0
  65. package/dist/utils/webhooks.d.ts +19 -4
  66. package/dist/utils/webhooks.d.ts.map +1 -1
  67. package/package.json +14 -4
package/dist/index.esm.js CHANGED
@@ -2,14 +2,19 @@ import fetch from 'cross-fetch';
2
2
 
3
3
  class HttpClient {
4
4
  constructor(config) {
5
+ // Compute endpoint from mode
6
+ const endpoint = config.mode === 'sandbox'
7
+ ? 'https://api-dev.inkress.com'
8
+ : 'https://api.inkress.com';
5
9
  this.config = {
6
- endpoint: 'https://api.inkress.com',
7
- apiVersion: 'v1',
8
- clientId: '',
9
- timeout: 30000,
10
- retries: 0,
11
- headers: {},
12
- ...config,
10
+ accessToken: config.accessToken,
11
+ mode: config.mode || 'live',
12
+ apiVersion: config.apiVersion || 'v1',
13
+ username: config.username || '',
14
+ timeout: config.timeout || 30000,
15
+ retries: config.retries || 0,
16
+ headers: config.headers || {},
17
+ endpoint, // computed from mode
13
18
  };
14
19
  }
15
20
  getBaseUrl() {
@@ -19,13 +24,13 @@ class HttpClient {
19
24
  getHeaders(additionalHeaders = {}) {
20
25
  const headers = {
21
26
  'Content-Type': 'application/json',
22
- 'Authorization': `Bearer ${this.config.bearerToken}`,
27
+ 'Authorization': `Bearer ${this.config.accessToken}`,
23
28
  ...this.config.headers,
24
29
  ...additionalHeaders,
25
30
  };
26
- // Add Client-Id header if provided
27
- if (this.config.clientId) {
28
- headers['Client-Id'] = this.config.clientId;
31
+ // Add Client-Id header if username is provided (prepend with 'm-')
32
+ if (this.config.username) {
33
+ headers['Client-Id'] = `m-${this.config.username}`;
29
34
  }
30
35
  return headers;
31
36
  }
@@ -63,7 +68,7 @@ class HttpClient {
63
68
  }
64
69
  const responseText = await response.text();
65
70
  if (!responseText) {
66
- return { state: 'ok', data: undefined };
71
+ return { state: 'ok', result: undefined };
67
72
  }
68
73
  const data = JSON.parse(responseText);
69
74
  return data;
@@ -127,322 +132,4301 @@ class HttpClient {
127
132
  }
128
133
  // Update configuration
129
134
  updateConfig(newConfig) {
130
- this.config = { ...this.config, ...newConfig };
135
+ // Recompute endpoint if mode changes
136
+ if (newConfig.mode) {
137
+ const endpoint = newConfig.mode === 'sandbox'
138
+ ? 'https://api-dev.inkress.com'
139
+ : 'https://api.inkress.com';
140
+ this.config = { ...this.config, ...newConfig, endpoint };
141
+ }
142
+ else {
143
+ this.config = { ...this.config, ...newConfig };
144
+ }
145
+ }
146
+ // Get current configuration (without sensitive data)
147
+ getConfig() {
148
+ const { accessToken, ...config } = this.config;
149
+ // Remove computed endpoint from config
150
+ const { endpoint, ...publicConfig } = config;
151
+ return publicConfig;
152
+ }
153
+ }
154
+ class InkressApiError extends Error {
155
+ constructor(message, status, result) {
156
+ super(message);
157
+ this.name = 'InkressApiError';
158
+ this.status = status;
159
+ this.result = result;
160
+ }
161
+ }
162
+
163
+ const mappings = {
164
+ "Access": {
165
+ "view": 1,
166
+ "list": 2,
167
+ "create": 3,
168
+ "update": 4,
169
+ "delete": 5
170
+ },
171
+ "FeeStructure": {
172
+ "merchant_absorb": 1,
173
+ "customer_pay": 2
174
+ },
175
+ "Kind": {
176
+ "order_online": 1,
177
+ "order_payment_link": 1,
178
+ "order_cart": 2,
179
+ "order_subscription": 3,
180
+ "order_invoice": 4,
181
+ "order_offline": 5,
182
+ "template_email": 1,
183
+ "template_sms": 2,
184
+ "template_receipt": 3,
185
+ "password_account": 4,
186
+ "password_otp": 5,
187
+ "legal_request_account_removal": 6,
188
+ "legal_request_account_report": 7,
189
+ "notification_sale": 8,
190
+ "notification_invite": 9,
191
+ "notification_registration": 10,
192
+ "notification_account": 11,
193
+ "notification_report": 12,
194
+ "notification_auth": 13,
195
+ "notification_cart_reminder": 14,
196
+ "notification_product_reminder": 15,
197
+ "notification_purchase_confirmation": 16,
198
+ "notification_shipping_confirmation": 17,
199
+ "notification_delivery_confirmation": 18,
200
+ "notification_feedback_request": 19,
201
+ "notification_review_request": 20,
202
+ "notification_platform_announcement": 21,
203
+ "notification_organisation_announcement": 22,
204
+ "notification_store_announcement": 23,
205
+ "notification_organisation_suggestion": 24,
206
+ "notification_store_suggestion": 25,
207
+ "notification_organisation_referral": 26,
208
+ "notification_store_referral": 27,
209
+ "notification_organisation_upsell": 28,
210
+ "notification_store_upsell": 29,
211
+ "transaction_order": 30,
212
+ "transaction_payout": 31,
213
+ "transaction_manual": 32,
214
+ "transaction_fee": 33,
215
+ "token_login": 24,
216
+ "token_api": 25,
217
+ "token_sso": 32,
218
+ "token_preset": 33,
219
+ "user_address": 35,
220
+ "merchant_address": 36,
221
+ "organisation_address": 37,
222
+ "role_preset": 26,
223
+ "role_organisation": 27,
224
+ "role_store": 28,
225
+ "product_draft": 29,
226
+ "product_published": 30,
227
+ "product_archived": 31,
228
+ "file_business_logo": 51,
229
+ "file_business_document": 50,
230
+ "file_payout_document": 71,
231
+ "identity_email": 52,
232
+ "identity_phone": 53,
233
+ "billing_plan_subscription": 1,
234
+ "billing_plan_payout": 2,
235
+ "billing_subscription_manual_charge": 1,
236
+ "billing_subscription_auto_charge": 2,
237
+ "ledger_entry_credit": 1,
238
+ "ledger_entry_debit": 2,
239
+ "ledger_payout_standard": 1,
240
+ "ledger_payout_early": 2,
241
+ "ledger_payout_manual": 10,
242
+ "fee_transaction_platform": 1,
243
+ "fee_transaction_provider": 2,
244
+ "fee_transaction_tax": 3,
245
+ "fee_transaction_discount": 4,
246
+ "fee_transaction_shipping": 5,
247
+ "fee_transaction_processing": 6,
248
+ "fee_transaction_subscription": 7,
249
+ "fee_transaction_payout": 8,
250
+ "fee_transaction_refund": 9,
251
+ "fee_transaction_adjustment": 10,
252
+ "fee_merchant_daily_limit": 11,
253
+ "fee_merchant_weekly_limit": 12,
254
+ "fee_merchant_monthly_limit": 13,
255
+ "fee_merchant_single_limit": 14,
256
+ "fee_merchant_withdrawal_limit": 15,
257
+ "legal_request_document_submission": 1,
258
+ "legal_request_bank_info_update": 2,
259
+ "legal_request_limit_increase": 3,
260
+ "payment_link_order": 1,
261
+ "payment_link_invoice": 2
262
+ },
263
+ "Status": {
264
+ "order_pending": 1,
265
+ "order_error": 2,
266
+ "order_failed": 2,
267
+ "order_paid": 3,
268
+ "order_partial": 32,
269
+ "order_confirmed": 4,
270
+ "order_cancelled": 5,
271
+ "order_prepared": 6,
272
+ "order_shipped": 7,
273
+ "order_delivered": 8,
274
+ "order_completed": 9,
275
+ "order_returned": 10,
276
+ "order_refunded": 11,
277
+ "order_verifying": 12,
278
+ "order_stale": 13,
279
+ "order_archived": 14,
280
+ "transaction_pending": 1,
281
+ "transaction_authorized": 2,
282
+ "transaction_hold": 3,
283
+ "transaction_captured": 4,
284
+ "transaction_voided": 5,
285
+ "transaction_refunded": 6,
286
+ "transaction_processed": 7,
287
+ "transaction_processing": 8,
288
+ "transaction_cancelled": 9,
289
+ "transaction_failed": 10,
290
+ "transaction_credit": 11,
291
+ "transaction_debit": 12,
292
+ "account_unverified": 20,
293
+ "account_verified": 21,
294
+ "account_in_review": 22,
295
+ "account_approved": 23,
296
+ "account_active": 24,
297
+ "account_paused": 25,
298
+ "account_restricted": 26,
299
+ "account_suspended": 27,
300
+ "account_banned": 28,
301
+ "account_resigned": 29,
302
+ "account_archived": 30,
303
+ "email_outdated": 31,
304
+ "identity_unverified": 32,
305
+ "identity_verified": 33,
306
+ "identity_in_review": 34,
307
+ "identity_archived": 35,
308
+ "identity_rejected": 36,
309
+ "billing_subscription_pending": 1,
310
+ "billing_subscription_active": 2,
311
+ "billing_subscription_cancelled": 3,
312
+ "billing_subscription_adhoc_charged": 4,
313
+ "ledger_payout_pending": 1,
314
+ "ledger_payout_processing": 2,
315
+ "ledger_payout_processed": 3,
316
+ "ledger_payout_rejected": 4,
317
+ "ledger_entry_pending": 1,
318
+ "ledger_entry_processing": 2,
319
+ "ledger_entry_processed": 3,
320
+ "billing_plan_active": 1,
321
+ "billing_plan_draft": 2,
322
+ "billing_plan_archived": 3,
323
+ "post_draft": 1,
324
+ "post_published": 2,
325
+ "post_archived": 3,
326
+ "product_draft": 1,
327
+ "product_published": 2,
328
+ "product_archived": 3,
329
+ "legal_request_pending": 1,
330
+ "legal_request_in_review": 2,
331
+ "legal_request_approved": 3,
332
+ "legal_request_rejected": 4,
333
+ "financial_request_pending": 1,
334
+ "financial_request_in_review": 2,
335
+ "financial_request_approved": 3,
336
+ "financial_request_rejected": 4
337
+ }
338
+ };
339
+
340
+ // Translation utilities for converting between string representations and integer values
341
+ // Create reverse mappings for integer to string conversion
342
+ const createReverseMapping = (mapping) => {
343
+ const reversed = {};
344
+ for (const [key, value] of Object.entries(mapping)) {
345
+ reversed[value] = key;
346
+ }
347
+ return reversed;
348
+ };
349
+ const reverseFeeStructure = createReverseMapping(mappings.FeeStructure);
350
+ const reverseKind = createReverseMapping(mappings.Kind);
351
+ const reverseStatus = createReverseMapping(mappings.Status);
352
+ createReverseMapping(mappings.Access);
353
+ /**
354
+ * Translation functions for Fee Structures
355
+ */
356
+ const FeeStructureTranslator = {
357
+ /**
358
+ * Convert string to integer for API calls
359
+ */
360
+ toInteger(key) {
361
+ return mappings.FeeStructure[key];
362
+ },
363
+ /**
364
+ * Convert integer to string for user display
365
+ */
366
+ toString(value) {
367
+ const key = reverseFeeStructure[value];
368
+ if (!key) {
369
+ throw new Error(`Unknown fee structure value: ${value}`);
370
+ }
371
+ return key;
372
+ },
373
+ /**
374
+ * Get all available options as string keys
375
+ */
376
+ getOptions() {
377
+ return Object.keys(mappings.FeeStructure);
378
+ }
379
+ };
380
+ /**
381
+ * Translation functions for Kinds with context-aware prefixing
382
+ */
383
+ const KindTranslator = {
384
+ /**
385
+ * Convert string to integer for API calls
386
+ */
387
+ toInteger(key) {
388
+ return mappings.Kind[key];
389
+ },
390
+ /**
391
+ * Convert string to integer with context prefix
392
+ */
393
+ toIntegerWithContext(key, context) {
394
+ // If key already has a context prefix, use as-is
395
+ const fullKey = key.includes('_') ? key : `${context}_${key}`;
396
+ if (mappings.Kind[fullKey] !== undefined) {
397
+ return mappings.Kind[fullKey];
398
+ }
399
+ // Fallback: try the key as-is if it's a valid kind
400
+ if (mappings.Kind[key] !== undefined) {
401
+ return mappings.Kind[key];
402
+ }
403
+ throw new Error(`Unknown kind value: ${key} (tried with context: ${fullKey})`);
404
+ },
405
+ /**
406
+ * Convert integer to string for user display
407
+ */
408
+ toString(value) {
409
+ const key = reverseKind[value];
410
+ if (!key) {
411
+ throw new Error(`Unknown kind value: ${value}`);
412
+ }
413
+ return key;
414
+ },
415
+ /**
416
+ * Convert integer to string and remove context prefix
417
+ */
418
+ toStringWithoutContext(value, context) {
419
+ const fullKey = this.toString(value);
420
+ const prefix = `${context}_`;
421
+ if (fullKey.startsWith(prefix)) {
422
+ return fullKey.substring(prefix.length);
423
+ }
424
+ return fullKey;
425
+ },
426
+ /**
427
+ * Get all available options as string keys
428
+ */
429
+ getOptions() {
430
+ return Object.keys(mappings.Kind);
431
+ },
432
+ /**
433
+ * Get options filtered by prefix (e.g., 'order_', 'product_')
434
+ */
435
+ getOptionsByPrefix(prefix) {
436
+ return this.getOptions().filter(key => key.startsWith(prefix));
437
+ },
438
+ /**
439
+ * Get options without context prefix for a specific context
440
+ */
441
+ getContextualOptions(context) {
442
+ const prefix = `${context}_`;
443
+ return this.getOptions()
444
+ .filter(key => key.startsWith(prefix))
445
+ .map(key => key.substring(prefix.length));
446
+ }
447
+ };
448
+ /**
449
+ * Translation functions for Statuses with context-aware prefixing
450
+ */
451
+ const StatusTranslator = {
452
+ /**
453
+ * Convert string to integer for API calls
454
+ */
455
+ toInteger(key) {
456
+ return mappings.Status[key];
457
+ },
458
+ /**
459
+ * Convert string to integer with context prefix
460
+ */
461
+ toIntegerWithContext(key, context) {
462
+ // If key already has the context prefix, use as-is
463
+ const fullKey = key.includes('_') ? key : `${context}_${key}`;
464
+ if (mappings.Status[fullKey] !== undefined) {
465
+ return mappings.Status[fullKey];
466
+ }
467
+ // Fallback: try the key as-is if it's a valid status
468
+ if (mappings.Status[key] !== undefined) {
469
+ return mappings.Status[key];
470
+ }
471
+ throw new Error(`Unknown status value: ${key} (tried with context: ${fullKey})`);
472
+ },
473
+ /**
474
+ * Convert integer to string for user display
475
+ */
476
+ toString(value) {
477
+ const key = reverseStatus[value];
478
+ if (!key) {
479
+ throw new Error(`Unknown status value: ${value}`);
480
+ }
481
+ return key;
482
+ },
483
+ /**
484
+ * Convert integer to string and remove context prefix
485
+ */
486
+ toStringWithoutContext(value, context) {
487
+ const fullKey = this.toString(value);
488
+ const prefix = `${context}_`;
489
+ if (fullKey.startsWith(prefix)) {
490
+ return fullKey.substring(prefix.length);
491
+ }
492
+ return fullKey;
493
+ },
494
+ /**
495
+ * Get all available options as string keys
496
+ */
497
+ getOptions() {
498
+ return Object.keys(mappings.Status);
499
+ },
500
+ /**
501
+ * Get options filtered by prefix (e.g., 'order_', 'product_', 'account_')
502
+ */
503
+ getOptionsByPrefix(prefix) {
504
+ return this.getOptions().filter(key => key.startsWith(prefix));
505
+ },
506
+ /**
507
+ * Get options without context prefix for a specific context
508
+ */
509
+ getContextualOptions(context) {
510
+ const prefix = `${context}_`;
511
+ return this.getOptions()
512
+ .filter(key => key.startsWith(prefix))
513
+ .map(key => key.substring(prefix.length));
514
+ }
515
+ };
516
+
517
+ /**
518
+ * Type-Based Query System
519
+ *
520
+ * This module provides a clean, type-safe query API where users write intuitive queries
521
+ * and the SDK automatically transforms them into the Elixir-compatible format.
522
+ *
523
+ * Features:
524
+ * - Array values → _in suffix (id: [1,2,3] → id_in: [1,2,3])
525
+ * - Range objects → _min/_max suffixes (age: {min: 18, max: 65} → age_min: 18, age_max: 65)
526
+ * - String operations → contains. prefix (name: {contains: "john"} → "contains.name": "john")
527
+ * - Date operations → before./after./on. prefixes
528
+ * - JSON field operations → in_, not_, null_, not_null_ prefixes
529
+ * - Direct values → equality check (no transformation)
530
+ */
531
+ /**
532
+ * Runtime validation for query parameters
533
+ */
534
+ function validateQueryParams(query, fieldTypes) {
535
+ const errors = [];
536
+ if (!query || typeof query !== 'object') {
537
+ return errors;
538
+ }
539
+ for (const [key, value] of Object.entries(query)) {
540
+ // Skip special fields and undefined/null values
541
+ if (isSpecialField(key) || value === undefined || value === null) {
542
+ continue;
543
+ }
544
+ // Skip data field (JSON queries have their own validation)
545
+ if (key === 'data') {
546
+ continue;
547
+ }
548
+ const fieldType = fieldTypes === null || fieldTypes === void 0 ? void 0 : fieldTypes[key];
549
+ // Validate based on field type
550
+ if (fieldType) {
551
+ const validationError = validateFieldValue(key, value, fieldType);
552
+ if (validationError) {
553
+ errors.push(validationError);
554
+ }
555
+ }
556
+ }
557
+ return errors;
558
+ }
559
+ /**
560
+ * Validate a single field value against its expected type
561
+ */
562
+ function validateFieldValue(fieldName, value, expectedType) {
563
+ // Handle array values (for _in operations)
564
+ if (Array.isArray(value)) {
565
+ for (const item of value) {
566
+ if (!isValueOfType(item, expectedType)) {
567
+ return `Field "${fieldName}" array contains invalid type. Expected all items to be ${expectedType}, but found ${typeof item}`;
568
+ }
569
+ }
570
+ return null;
571
+ }
572
+ // Handle range objects
573
+ if (typeof value === 'object' && value !== null && ('min' in value || 'max' in value)) {
574
+ if (expectedType !== 'number' && expectedType !== 'date' && expectedType !== 'string') {
575
+ return `Field "${fieldName}" cannot use range queries. Range queries are only supported for number, date, and string fields.`;
576
+ }
577
+ if ('min' in value && value.min !== undefined && !isValueOfType(value.min, expectedType)) {
578
+ return `Field "${fieldName}" range min value has wrong type. Expected ${expectedType}, got ${typeof value.min}`;
579
+ }
580
+ if ('max' in value && value.max !== undefined && !isValueOfType(value.max, expectedType)) {
581
+ return `Field "${fieldName}" range max value has wrong type. Expected ${expectedType}, got ${typeof value.max}`;
582
+ }
583
+ return null;
584
+ }
585
+ // Handle string contains queries
586
+ if (typeof value === 'object' && value !== null && 'contains' in value) {
587
+ if (expectedType !== 'string') {
588
+ return `Field "${fieldName}" cannot use contains queries. Contains queries are only supported for string fields.`;
589
+ }
590
+ if (typeof value.contains !== 'string') {
591
+ return `Field "${fieldName}" contains value must be a string. Got ${typeof value.contains}`;
592
+ }
593
+ return null;
594
+ }
595
+ // Handle date queries
596
+ if (typeof value === 'object' && value !== null && ('before' in value || 'after' in value || 'on' in value || 'min' in value || 'max' in value)) {
597
+ if ('before' in value && value.before !== undefined && typeof value.before !== 'string') {
598
+ return `Field "${fieldName}" before value must be a string. Got ${typeof value.before}`;
599
+ }
600
+ if ('after' in value && value.after !== undefined && typeof value.after !== 'string') {
601
+ return `Field "${fieldName}" after value must be a string. Got ${typeof value.after}`;
602
+ }
603
+ if ('on' in value && value.on !== undefined && typeof value.on !== 'string') {
604
+ return `Field "${fieldName}" on value must be a string. Got ${typeof value.on}`;
605
+ }
606
+ if ('min' in value && value.min !== undefined && typeof value.min !== 'string') {
607
+ return `Field "${fieldName}" min value must be a string. Got ${typeof value.min}`;
608
+ }
609
+ if ('max' in value && value.max !== undefined && typeof value.max !== 'string') {
610
+ return `Field "${fieldName}" max value must be a string. Got ${typeof value.max}`;
611
+ }
612
+ return null;
613
+ }
614
+ // Handle direct values
615
+ if (!isValueOfType(value, expectedType)) {
616
+ return `Field "${fieldName}" has wrong type. Expected ${expectedType}, got ${typeof value}`;
617
+ }
618
+ return null;
619
+ }
620
+ /**
621
+ * Check if a value matches the expected type
622
+ */
623
+ function isValueOfType(value, expectedType) {
624
+ switch (expectedType) {
625
+ case 'string':
626
+ return typeof value === 'string';
627
+ case 'number':
628
+ return typeof value === 'number' && !isNaN(value);
629
+ case 'boolean':
630
+ return typeof value === 'boolean';
631
+ case 'date':
632
+ return value instanceof Date || (typeof value === 'string' && !isNaN(Date.parse(value)));
633
+ case 'array':
634
+ return Array.isArray(value);
635
+ default:
636
+ return true;
637
+ }
638
+ }
639
+ /**
640
+ * Transform a clean user query into Elixir-compatible format
641
+ */
642
+ function transformQuery(query) {
643
+ if (!query || typeof query !== 'object') {
644
+ return {};
645
+ }
646
+ const result = {};
647
+ for (const [key, value] of Object.entries(query)) {
648
+ // Skip undefined/null values
649
+ if (value === undefined || value === null) {
650
+ continue;
651
+ }
652
+ // Pass through special fields unchanged
653
+ if (isSpecialField(key)) {
654
+ result[key] = value;
655
+ continue;
656
+ }
657
+ // Handle data field specially for JSON queries
658
+ if (key === 'data' && typeof value === 'object') {
659
+ result.data = transformJsonQuery(value);
660
+ continue;
661
+ }
662
+ // Transform based on value type
663
+ const transformedValue = transformFieldValue(key, value);
664
+ // Skip null values (e.g., from empty objects)
665
+ if (transformedValue !== null) {
666
+ result[key] = transformedValue;
667
+ }
668
+ }
669
+ return result;
670
+ }
671
+ /**
672
+ * Check if a field is a special field that should pass through unchanged
673
+ */
674
+ function isSpecialField(key) {
675
+ const specialFields = [
676
+ 'exclude', 'distinct', 'order_by', 'page', 'page_size', 'per_page',
677
+ 'limit', 'override_page', 'q', 'search', 'sort', 'order'
678
+ ];
679
+ return specialFields.includes(key);
680
+ }
681
+ /**
682
+ * Transform a field value based on its type
683
+ */
684
+ function transformFieldValue(key, value) {
685
+ if (Array.isArray(value)) {
686
+ // Array → add _in suffix
687
+ return { [`${key}_in`]: value };
688
+ }
689
+ if (typeof value === 'object' && value !== null) {
690
+ const transformedObject = {};
691
+ // Handle range queries (min/max)
692
+ if ('min' in value && value.min !== undefined) {
693
+ transformedObject[`${key}_min`] = value.min;
694
+ }
695
+ if ('max' in value && value.max !== undefined) {
696
+ transformedObject[`${key}_max`] = value.max;
697
+ }
698
+ // Handle range queries (gte/lte/gt/lt)
699
+ if ('gte' in value && value.gte !== undefined) {
700
+ transformedObject[`${key}_gte`] = value.gte;
701
+ }
702
+ if ('lte' in value && value.lte !== undefined) {
703
+ transformedObject[`${key}_lte`] = value.lte;
704
+ }
705
+ if ('gt' in value && value.gt !== undefined) {
706
+ transformedObject[`${key}_gt`] = value.gt;
707
+ }
708
+ if ('lt' in value && value.lt !== undefined) {
709
+ transformedObject[`${key}_lt`] = value.lt;
710
+ }
711
+ // Handle string queries
712
+ if ('contains' in value && value.contains !== undefined) {
713
+ transformedObject[`contains.${key}`] = value.contains;
714
+ }
715
+ // Handle date queries
716
+ if ('before' in value && value.before !== undefined) {
717
+ transformedObject[`before.${key}`] = value.before;
718
+ }
719
+ if ('after' in value && value.after !== undefined) {
720
+ transformedObject[`after.${key}`] = value.after;
721
+ }
722
+ if ('on' in value && value.on !== undefined) {
723
+ transformedObject[`on.${key}`] = value.on;
724
+ }
725
+ // If we found any transformations, return them
726
+ if (Object.keys(transformedObject).length > 0) {
727
+ return transformedObject;
728
+ }
729
+ // Empty object with no transformation keys - return null to skip it
730
+ if (Object.keys(value).length === 0) {
731
+ return null;
732
+ }
733
+ }
734
+ // Direct value → wrap for consistent structure that will be flattened later
735
+ return { [key]: value };
736
+ }
737
+ /**
738
+ * Transform JSON field queries with special operators
739
+ */
740
+ function transformJsonQuery(data) {
741
+ const result = {};
742
+ for (const [key, value] of Object.entries(data)) {
743
+ // Skip undefined/null values
744
+ if (value === undefined || value === null) {
745
+ continue;
746
+ }
747
+ // Nested paths (e.g., "settings->theme") stay as-is
748
+ if (key.includes('->')) {
749
+ result[key] = value;
750
+ continue;
751
+ }
752
+ if (typeof value === 'object' && value !== null) {
753
+ // Check if this is a JSON query operation (has special keys)
754
+ const hasJsonQueryOps = 'in' in value || 'not' in value || 'null' in value ||
755
+ 'not_null' in value || 'min' in value || 'max' in value;
756
+ if (hasJsonQueryOps) {
757
+ // Transform JSON-specific operations
758
+ if ('in' in value && value.in !== undefined) {
759
+ result[`in_${key}`] = value.in;
760
+ }
761
+ if ('not' in value && value.not !== undefined) {
762
+ result[`not_${key}`] = value.not;
763
+ }
764
+ if ('null' in value && value.null !== undefined) {
765
+ result[`null_${key}`] = value.null;
766
+ }
767
+ if ('not_null' in value && value.not_null !== undefined) {
768
+ result[`not_null_${key}`] = value.not_null;
769
+ }
770
+ if ('min' in value && value.min !== undefined) {
771
+ result[`${key}_min`] = value.min;
772
+ }
773
+ if ('max' in value && value.max !== undefined) {
774
+ result[`${key}_max`] = value.max;
775
+ }
776
+ }
777
+ else {
778
+ // Complex object without query operators - pass through as-is
779
+ result[key] = value;
780
+ }
781
+ }
782
+ else {
783
+ // Direct value in JSON field
784
+ result[key] = value;
785
+ }
786
+ }
787
+ return result;
788
+ }
789
+ /**
790
+ * Flatten the transformed query object for API consumption
791
+ */
792
+ function flattenTransformedQuery(transformed) {
793
+ const result = {};
794
+ for (const [key, value] of Object.entries(transformed)) {
795
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
796
+ // If it's a transformation object with special keys, merge its properties
797
+ if (hasTransformationKeys(value)) {
798
+ Object.assign(result, value);
799
+ }
800
+ else if (isWrappedDirectValue(key, value)) {
801
+ // Unwrap direct values like { id: { id: 5 } } → { id: 5 }
802
+ result[key] = value[key];
803
+ }
804
+ else {
805
+ // Regular object (like data field)
806
+ result[key] = value;
807
+ }
808
+ }
809
+ else {
810
+ // Direct value or array
811
+ result[key] = value;
812
+ }
813
+ }
814
+ return result;
815
+ }
816
+ /**
817
+ * Check if a value is a wrapped direct value (e.g., { id: { id: 5 } })
818
+ * This happens when transformFieldValue wraps a direct value for consistency
819
+ */
820
+ function isWrappedDirectValue(key, obj) {
821
+ const keys = Object.keys(obj);
822
+ return keys.length === 1 && keys[0] === key;
823
+ }
824
+ /**
825
+ * Check if an object contains transformation keys
826
+ */
827
+ function hasTransformationKeys(obj) {
828
+ const keys = Object.keys(obj);
829
+ return keys.some(key => key.includes('_min') ||
830
+ key.includes('_max') ||
831
+ key.includes('_gte') ||
832
+ key.includes('_lte') ||
833
+ key.includes('_gt') ||
834
+ key.includes('_lt') ||
835
+ key.includes('_in') ||
836
+ key.includes('contains.') ||
837
+ key.includes('before.') ||
838
+ key.includes('after.') ||
839
+ key.includes('on.'));
840
+ }
841
+ /**
842
+ * Main function to transform and flatten a query in one step
843
+ * Handles translation of contextual strings to integers before transformation
844
+ */
845
+ function processQuery(query, fieldTypes, options = { validate: false }) {
846
+ // Translate contextual strings to integers BEFORE validation and transformation
847
+ const translatedQuery = { ...query };
848
+ if (fieldTypes && options.context) {
849
+ for (const [key, value] of Object.entries(translatedQuery)) {
850
+ const fieldType = fieldTypes[key];
851
+ // Skip special fields
852
+ if (isSpecialField(key))
853
+ continue;
854
+ // Translate status fields (contextual strings to integers)
855
+ if (key === 'status' && fieldType === 'number') {
856
+ translatedQuery[key] = translateValue(value, StatusTranslator, options.context);
857
+ }
858
+ // Translate kind fields (contextual strings to integers)
859
+ if (key === 'kind' && fieldType === 'number') {
860
+ translatedQuery[key] = translateValue(value, KindTranslator, options.context);
861
+ }
862
+ }
863
+ }
864
+ // Transform AFTER translation so that range objects are properly handled
865
+ const transformed = transformQuery(translatedQuery);
866
+ const flattened = flattenTransformedQuery(transformed);
867
+ // Runtime validation AFTER transformation if enabled and field types provided
868
+ if (options.validate && fieldTypes) {
869
+ const validationErrors = validateQueryParams(flattened, fieldTypes);
870
+ if (validationErrors.length > 0) {
871
+ console.warn(`Query validation warnings: ${validationErrors.join(', ')}`);
872
+ }
873
+ }
874
+ return flattened;
875
+ }
876
+ /**
877
+ * Helper to translate a value (string, array of strings, or object with strings)
878
+ */
879
+ function translateValue(value, translator, context) {
880
+ if (value === undefined || value === null) {
881
+ return value;
882
+ }
883
+ // Handle arrays (for _in operations)
884
+ if (Array.isArray(value)) {
885
+ return value.map(item => {
886
+ // If it's already a number, pass it through
887
+ if (typeof item === 'number') {
888
+ return item;
889
+ }
890
+ // If it's a string, it MUST be translatable
891
+ if (typeof item === 'string') {
892
+ return context
893
+ ? translator.toIntegerWithContext(item, context)
894
+ : translator.toInteger(item);
895
+ }
896
+ return item;
897
+ });
898
+ }
899
+ // Handle range objects (e.g., { gte: 'paid', lte: 'confirmed' })
900
+ if (typeof value === 'object' && value !== null) {
901
+ const translated = {};
902
+ for (const [k, v] of Object.entries(value)) {
903
+ // If it's already a number, pass it through
904
+ if (typeof v === 'number') {
905
+ translated[k] = v;
906
+ }
907
+ // If it's a string, it MUST be translatable
908
+ else if (typeof v === 'string') {
909
+ translated[k] = context
910
+ ? translator.toIntegerWithContext(v, context)
911
+ : translator.toInteger(v);
912
+ }
913
+ else {
914
+ translated[k] = v;
915
+ }
916
+ }
917
+ return translated;
918
+ }
919
+ // Handle direct string values
920
+ if (typeof value === 'string') {
921
+ return context
922
+ ? translator.toIntegerWithContext(value, context)
923
+ : translator.toInteger(value);
924
+ }
925
+ // Already a number, pass through
926
+ return value;
927
+ }
928
+ /**
929
+ * Type-safe query builder for specific entity types
930
+ */
931
+ class QueryBuilder {
932
+ constructor(initialQuery) {
933
+ this.query = {};
934
+ if (initialQuery) {
935
+ this.query = { ...initialQuery };
936
+ }
937
+ }
938
+ /**
939
+ * Add a field equality condition
940
+ */
941
+ where(field, value) {
942
+ this.query[field] = value;
943
+ return this;
944
+ }
945
+ /**
946
+ * Add a field IN condition (array of values)
947
+ */
948
+ whereIn(field, values) {
949
+ this.query[field] = values;
950
+ return this;
951
+ }
952
+ /**
953
+ * Add a range condition (min/max)
954
+ */
955
+ whereRange(field, min, max) {
956
+ const range = {};
957
+ if (min !== undefined)
958
+ range.min = min;
959
+ if (max !== undefined)
960
+ range.max = max;
961
+ this.query[field] = range;
962
+ return this;
963
+ }
964
+ /**
965
+ * Add a string contains condition
966
+ */
967
+ whereContains(field, value) {
968
+ this.query[field] = { contains: value };
969
+ return this;
970
+ }
971
+ /**
972
+ * Add a date range condition
973
+ */
974
+ whereDateRange(field, after, before, on) {
975
+ const dateQuery = {};
976
+ if (after !== undefined)
977
+ dateQuery.after = after;
978
+ if (before !== undefined)
979
+ dateQuery.before = before;
980
+ if (on !== undefined)
981
+ dateQuery.on = on;
982
+ this.query[field] = dateQuery;
983
+ return this;
984
+ }
985
+ /**
986
+ * Add pagination
987
+ */
988
+ paginate(page, pageSize) {
989
+ this.query.page = page;
990
+ this.query.page_size = pageSize;
991
+ return this;
992
+ }
993
+ /**
994
+ * Add ordering
995
+ */
996
+ orderBy(field, direction = 'asc') {
997
+ this.query.order_by = `${field} ${direction}`;
998
+ return this;
999
+ }
1000
+ /**
1001
+ * Add general search
1002
+ */
1003
+ search(term) {
1004
+ this.query.q = term;
1005
+ return this;
1006
+ }
1007
+ /**
1008
+ * Build and return the transformed query
1009
+ */
1010
+ build() {
1011
+ return processQuery(this.query);
1012
+ }
1013
+ /**
1014
+ * Get the raw query (before transformation)
1015
+ */
1016
+ getRawQuery() {
1017
+ return { ...this.query };
1018
+ }
1019
+ }
1020
+
1021
+ /**
1022
+ * Resource-specific query builders
1023
+ *
1024
+ * This file provides fluent query builder interfaces for each resource type,
1025
+ * offering excellent IntelliSense and type safety for complex queries.
1026
+ */
1027
+ /**
1028
+ * Order Query Builder
1029
+ * Provides a fluent interface for building complex order queries
1030
+ *
1031
+ * @example
1032
+ * const orders = await sdk.orders.createQueryBuilder()
1033
+ * .whereStatus('confirmed')
1034
+ * .whereTotalRange(100, 1000)
1035
+ * .whereReferenceContains('ORDER-2024')
1036
+ * .paginate(1, 20)
1037
+ * .orderBy('inserted_at', 'desc')
1038
+ * .execute();
1039
+ */
1040
+ class OrderQueryBuilder extends QueryBuilder {
1041
+ constructor(resource, initialQuery) {
1042
+ super(initialQuery);
1043
+ this.resource = resource;
1044
+ }
1045
+ /**
1046
+ * Execute the query and return the results
1047
+ */
1048
+ async execute() {
1049
+ return this.resource.query(this.getRawQuery());
1050
+ }
1051
+ /**
1052
+ * Filter by order status (contextual values)
1053
+ */
1054
+ whereStatus(status) {
1055
+ if (Array.isArray(status)) {
1056
+ return this.whereIn('status', status);
1057
+ }
1058
+ return this.where('status', status);
1059
+ }
1060
+ /**
1061
+ * Filter by order kind/type (contextual values)
1062
+ */
1063
+ whereKind(kind) {
1064
+ if (Array.isArray(kind)) {
1065
+ return this.whereIn('kind', kind);
1066
+ }
1067
+ return this.where('kind', kind);
1068
+ }
1069
+ /**
1070
+ * Filter by total amount range
1071
+ */
1072
+ whereTotalRange(min, max) {
1073
+ return this.whereRange('total', min, max);
1074
+ }
1075
+ /**
1076
+ * Filter by reference ID containing a string
1077
+ */
1078
+ whereReferenceContains(value) {
1079
+ return this.whereContains('reference_id', value);
1080
+ }
1081
+ /**
1082
+ * Filter by creation date range
1083
+ */
1084
+ whereCreatedBetween(after, before) {
1085
+ return this.whereDateRange('inserted_at', after, before);
1086
+ }
1087
+ /**
1088
+ * Filter by customer ID
1089
+ */
1090
+ whereCustomer(customerId) {
1091
+ if (Array.isArray(customerId)) {
1092
+ return this.whereIn('customer_id', customerId);
1093
+ }
1094
+ return this.where('customer_id', customerId);
1095
+ }
1096
+ /**
1097
+ * Filter by billing plan ID
1098
+ */
1099
+ whereBillingPlan(planId) {
1100
+ if (Array.isArray(planId)) {
1101
+ return this.whereIn('billing_plan_id', planId);
1102
+ }
1103
+ return this.where('billing_plan_id', planId);
1104
+ }
1105
+ }
1106
+ /**
1107
+ * Product Query Builder
1108
+ * Provides a fluent interface for building complex product queries
1109
+ *
1110
+ * @example
1111
+ * const products = await sdk.products.createQueryBuilder()
1112
+ * .whereStatus('published')
1113
+ * .wherePriceRange(10, 100)
1114
+ * .whereTitleContains('shirt')
1115
+ * .wherePublic(true)
1116
+ * .paginate(1, 20)
1117
+ * .execute();
1118
+ */
1119
+ class ProductQueryBuilder extends QueryBuilder {
1120
+ constructor(resource, initialQuery) {
1121
+ super(initialQuery);
1122
+ this.resource = resource;
1123
+ }
1124
+ /**
1125
+ * Execute the query and return the results
1126
+ */
1127
+ async execute() {
1128
+ return this.resource.query(this.getRawQuery());
1129
+ }
1130
+ /**
1131
+ * Filter by product status
1132
+ */
1133
+ whereStatus(status) {
1134
+ if (Array.isArray(status)) {
1135
+ return this.whereIn('status', status);
1136
+ }
1137
+ return this.where('status', status);
1138
+ }
1139
+ /**
1140
+ * Filter by price range
1141
+ */
1142
+ wherePriceRange(min, max) {
1143
+ return this.whereRange('price', min, max);
1144
+ }
1145
+ /**
1146
+ * Filter by title containing a string
1147
+ */
1148
+ whereTitleContains(value) {
1149
+ return this.whereContains('title', value);
1150
+ }
1151
+ /**
1152
+ * Filter by public visibility
1153
+ */
1154
+ wherePublic(isPublic) {
1155
+ return this.where('public', isPublic);
1156
+ }
1157
+ /**
1158
+ * Filter by category
1159
+ */
1160
+ whereCategory(categoryId) {
1161
+ if (Array.isArray(categoryId)) {
1162
+ return this.whereIn('category_id', categoryId);
1163
+ }
1164
+ return this.where('category_id', categoryId);
1165
+ }
1166
+ /**
1167
+ * Filter by availability (units remaining)
1168
+ */
1169
+ whereUnitsRemainingRange(min, max) {
1170
+ return this.whereRange('units_remaining', min, max);
1171
+ }
1172
+ /**
1173
+ * Filter by unlimited flag
1174
+ */
1175
+ whereUnlimited(isUnlimited) {
1176
+ return this.where('unlimited', isUnlimited);
1177
+ }
1178
+ }
1179
+ /**
1180
+ * User Query Builder
1181
+ * Provides a fluent interface for building complex user queries
1182
+ *
1183
+ * @example
1184
+ * const users = await sdk.users.createQueryBuilder()
1185
+ * .whereStatus('approved')
1186
+ * .whereKind('organisation')
1187
+ * .whereEmailContains('@example.com')
1188
+ * .whereLevelRange(5, 10)
1189
+ * .paginate(1, 20)
1190
+ * .execute();
1191
+ */
1192
+ class UserQueryBuilder extends QueryBuilder {
1193
+ constructor(resource, initialQuery) {
1194
+ super(initialQuery);
1195
+ this.resource = resource;
1196
+ }
1197
+ /**
1198
+ * Execute the query and return the results
1199
+ */
1200
+ async execute() {
1201
+ return this.resource.query(this.getRawQuery());
1202
+ }
1203
+ /**
1204
+ * Filter by account status
1205
+ */
1206
+ whereStatus(status) {
1207
+ if (Array.isArray(status)) {
1208
+ return this.whereIn('status', status);
1209
+ }
1210
+ return this.where('status', status);
1211
+ }
1212
+ /**
1213
+ * Filter by user kind/type
1214
+ */
1215
+ whereKind(kind) {
1216
+ if (Array.isArray(kind)) {
1217
+ return this.whereIn('kind', kind);
1218
+ }
1219
+ return this.where('kind', kind);
1220
+ }
1221
+ /**
1222
+ * Filter by email containing a string
1223
+ */
1224
+ whereEmailContains(value) {
1225
+ return this.whereContains('email', value);
1226
+ }
1227
+ /**
1228
+ * Filter by username containing a string
1229
+ */
1230
+ whereUsernameContains(value) {
1231
+ return this.whereContains('username', value);
1232
+ }
1233
+ /**
1234
+ * Filter by user level range
1235
+ */
1236
+ whereLevelRange(min, max) {
1237
+ return this.whereRange('level', min, max);
1238
+ }
1239
+ /**
1240
+ * Filter by organization
1241
+ */
1242
+ whereOrganisation(orgId) {
1243
+ if (Array.isArray(orgId)) {
1244
+ return this.whereIn('organisation_id', orgId);
1245
+ }
1246
+ return this.where('organisation_id', orgId);
1247
+ }
1248
+ /**
1249
+ * Filter by role
1250
+ */
1251
+ whereRole(roleId) {
1252
+ if (Array.isArray(roleId)) {
1253
+ return this.whereIn('role_id', roleId);
1254
+ }
1255
+ return this.where('role_id', roleId);
1256
+ }
1257
+ }
1258
+ /**
1259
+ * Merchant Query Builder
1260
+ * Provides a fluent interface for building complex merchant queries
1261
+ *
1262
+ * @example
1263
+ * const merchants = await sdk.merchants.createQueryBuilder()
1264
+ * .whereStatus('approved')
1265
+ * .whereNameContains('Store')
1266
+ * .whereSector('retail')
1267
+ * .paginate(1, 20)
1268
+ * .execute();
1269
+ */
1270
+ class MerchantQueryBuilder extends QueryBuilder {
1271
+ constructor(resource, initialQuery) {
1272
+ super(initialQuery);
1273
+ this.resource = resource;
1274
+ }
1275
+ /**
1276
+ * Execute the query and return the results
1277
+ */
1278
+ async execute() {
1279
+ return this.resource.query(this.getRawQuery());
1280
+ }
1281
+ /**
1282
+ * Filter by merchant status
1283
+ */
1284
+ whereStatus(status) {
1285
+ if (Array.isArray(status)) {
1286
+ return this.whereIn('status', status);
1287
+ }
1288
+ return this.where('status', status);
1289
+ }
1290
+ /**
1291
+ * Filter by name containing a string
1292
+ */
1293
+ whereNameContains(value) {
1294
+ return this.whereContains('name', value);
1295
+ }
1296
+ /**
1297
+ * Filter by email containing a string
1298
+ */
1299
+ whereEmailContains(value) {
1300
+ return this.whereContains('email', value);
1301
+ }
1302
+ /**
1303
+ * Filter by sector
1304
+ */
1305
+ whereSector(sector) {
1306
+ if (Array.isArray(sector)) {
1307
+ return this.whereIn('sector', sector);
1308
+ }
1309
+ return this.where('sector', sector);
1310
+ }
1311
+ /**
1312
+ * Filter by business type
1313
+ */
1314
+ whereBusinessType(type) {
1315
+ if (Array.isArray(type)) {
1316
+ return this.whereIn('business_type', type);
1317
+ }
1318
+ return this.where('business_type', type);
1319
+ }
1320
+ /**
1321
+ * Filter by platform fee structure
1322
+ */
1323
+ wherePlatformFeeStructure(structure) {
1324
+ if (Array.isArray(structure)) {
1325
+ return this.whereIn('platform_fee_structure', structure);
1326
+ }
1327
+ return this.where('platform_fee_structure', structure);
1328
+ }
1329
+ /**
1330
+ * Filter by organisation
1331
+ */
1332
+ whereOrganisation(orgId) {
1333
+ if (Array.isArray(orgId)) {
1334
+ return this.whereIn('organisation_id', orgId);
1335
+ }
1336
+ return this.where('organisation_id', orgId);
1337
+ }
1338
+ }
1339
+ /**
1340
+ * Category Query Builder
1341
+ * Provides a fluent interface for building complex category queries
1342
+ *
1343
+ * @example
1344
+ * const categories = await sdk.categories.createQueryBuilder()
1345
+ * .whereKind('published')
1346
+ * .whereNameContains('Electronics')
1347
+ * .whereParent(null)
1348
+ * .paginate(1, 20)
1349
+ * .execute();
1350
+ */
1351
+ class CategoryQueryBuilder extends QueryBuilder {
1352
+ constructor(resource, initialQuery) {
1353
+ super(initialQuery);
1354
+ this.resource = resource;
1355
+ }
1356
+ /**
1357
+ * Execute the query and return the results
1358
+ */
1359
+ async execute() {
1360
+ return this.resource.query(this.getRawQuery());
1361
+ }
1362
+ /**
1363
+ * Filter by category kind
1364
+ */
1365
+ whereKind(kind) {
1366
+ if (Array.isArray(kind)) {
1367
+ return this.whereIn('kind', kind);
1368
+ }
1369
+ return this.where('kind', kind);
1370
+ }
1371
+ /**
1372
+ * Filter by name containing a string
1373
+ */
1374
+ whereNameContains(value) {
1375
+ return this.whereContains('name', value);
1376
+ }
1377
+ /**
1378
+ * Filter by parent category
1379
+ */
1380
+ whereParent(parentId) {
1381
+ if (parentId === null) {
1382
+ return this.where('parent_id', null);
1383
+ }
1384
+ if (Array.isArray(parentId)) {
1385
+ return this.whereIn('parent_id', parentId);
1386
+ }
1387
+ return this.where('parent_id', parentId);
1388
+ }
1389
+ /**
1390
+ * Filter by root categories only (no parent)
1391
+ */
1392
+ whereRootOnly() {
1393
+ return this.where('parent_id', null);
1394
+ }
1395
+ }
1396
+ /**
1397
+ * Billing Plan Query Builder
1398
+ * Provides a fluent interface for building complex billing plan queries
1399
+ *
1400
+ * @example
1401
+ * const plans = await sdk.billingPlans.createQueryBuilder()
1402
+ * .whereKind('subscription')
1403
+ * .wherePriceRange(10, 100)
1404
+ * .wherePublic(true)
1405
+ * .paginate(1, 20)
1406
+ * .execute();
1407
+ */
1408
+ class BillingPlanQueryBuilder extends QueryBuilder {
1409
+ constructor(resource, initialQuery) {
1410
+ super(initialQuery);
1411
+ this.resource = resource;
1412
+ }
1413
+ /**
1414
+ * Execute the query and return the results
1415
+ */
1416
+ async execute() {
1417
+ return this.resource.query(this.getRawQuery());
1418
+ }
1419
+ /**
1420
+ * Filter by plan kind/type
1421
+ */
1422
+ whereKind(kind) {
1423
+ if (Array.isArray(kind)) {
1424
+ return this.whereIn('kind', kind);
1425
+ }
1426
+ return this.where('kind', kind);
1427
+ }
1428
+ /**
1429
+ * Filter by flat rate range
1430
+ */
1431
+ whereFlatRateRange(min, max) {
1432
+ return this.whereRange('flat_rate', min, max);
1433
+ }
1434
+ /**
1435
+ * Filter by transaction fee range
1436
+ */
1437
+ whereTransactionFeeRange(min, max) {
1438
+ return this.whereRange('transaction_fee', min, max);
1439
+ }
1440
+ /**
1441
+ * Filter by public visibility
1442
+ */
1443
+ wherePublic(isPublic) {
1444
+ return this.where('public', isPublic);
1445
+ }
1446
+ /**
1447
+ * Filter by auto charge
1448
+ */
1449
+ whereAutoCharge(autoCharge) {
1450
+ return this.where('auto_charge', autoCharge);
1451
+ }
1452
+ /**
1453
+ * Filter by name containing a string
1454
+ */
1455
+ whereNameContains(value) {
1456
+ return this.whereContains('name', value);
1457
+ }
1458
+ /**
1459
+ * Filter by duration range (in days)
1460
+ */
1461
+ whereDurationRange(min, max) {
1462
+ return this.whereRange('duration', min, max);
1463
+ }
1464
+ }
1465
+ /**
1466
+ * Subscription Query Builder
1467
+ * Provides a fluent interface for building complex subscription queries
1468
+ *
1469
+ * @example
1470
+ * const subscriptions = await sdk.subscriptions.createQueryBuilder()
1471
+ * .whereStatus('active')
1472
+ * .whereBillingPlan(123)
1473
+ * .whereStartDateAfter('2024-01-01')
1474
+ * .paginate(1, 20)
1475
+ * .execute();
1476
+ */
1477
+ class SubscriptionQueryBuilder extends QueryBuilder {
1478
+ constructor(resource, initialQuery) {
1479
+ super(initialQuery);
1480
+ this.resource = resource;
1481
+ }
1482
+ /**
1483
+ * Execute the query and return the results
1484
+ */
1485
+ async execute() {
1486
+ return this.resource.query(this.getRawQuery());
1487
+ }
1488
+ /**
1489
+ * Filter by subscription status
1490
+ */
1491
+ whereStatus(status) {
1492
+ if (Array.isArray(status)) {
1493
+ return this.whereIn('status', status);
1494
+ }
1495
+ return this.where('status', status);
1496
+ }
1497
+ /**
1498
+ * Filter by billing plan
1499
+ */
1500
+ whereBillingPlan(planId) {
1501
+ if (Array.isArray(planId)) {
1502
+ return this.whereIn('billing_plan_id', planId);
1503
+ }
1504
+ return this.where('billing_plan_id', planId);
1505
+ }
1506
+ /**
1507
+ * Filter by customer
1508
+ */
1509
+ whereCustomer(customerId) {
1510
+ if (Array.isArray(customerId)) {
1511
+ return this.whereIn('customer_id', customerId);
1512
+ }
1513
+ return this.where('customer_id', customerId);
1514
+ }
1515
+ /**
1516
+ * Filter by start date after a specific date
1517
+ */
1518
+ whereStartDateAfter(date) {
1519
+ return this.whereDateRange('start_date', date, undefined);
1520
+ }
1521
+ /**
1522
+ * Filter by start date before a specific date
1523
+ */
1524
+ whereStartDateBefore(date) {
1525
+ return this.whereDateRange('start_date', undefined, date);
1526
+ }
1527
+ /**
1528
+ * Filter by active subscriptions (not canceled)
1529
+ */
1530
+ whereActive() {
1531
+ return this.where('canceled_at', null);
1532
+ }
1533
+ /**
1534
+ * Filter by canceled subscriptions
1535
+ */
1536
+ whereCanceled() {
1537
+ // This would need a "not null" check which might require additional logic
1538
+ // For now, we can use a date range that's been filled
1539
+ return this.whereDateRange('canceled_at', '1970-01-01', undefined);
1540
+ }
1541
+ }
1542
+ /**
1543
+ * Payment Link Query Builder
1544
+ */
1545
+ class PaymentLinkQueryBuilder extends QueryBuilder {
1546
+ constructor(resource, initialQuery) {
1547
+ super(initialQuery);
1548
+ this.resource = resource;
1549
+ }
1550
+ async execute() {
1551
+ return this.resource.query(this.getRawQuery());
1552
+ }
1553
+ whereTotalGreaterThan(amount) {
1554
+ return this.whereRange('total', amount, undefined);
1555
+ }
1556
+ whereTotalLessThan(amount) {
1557
+ return this.whereRange('total', undefined, amount);
1558
+ }
1559
+ whereStatusIn(statuses) {
1560
+ return this.whereIn('status', statuses);
1561
+ }
1562
+ whereKindIn(kinds) {
1563
+ return this.whereIn('kind', kinds);
1564
+ }
1565
+ }
1566
+ /**
1567
+ * Financial Account Query Builder
1568
+ */
1569
+ class FinancialAccountQueryBuilder extends QueryBuilder {
1570
+ constructor(resource, initialQuery) {
1571
+ super(initialQuery);
1572
+ this.resource = resource;
1573
+ }
1574
+ async execute() {
1575
+ return this.resource.query(this.getRawQuery());
1576
+ }
1577
+ whereTypeEquals(type) {
1578
+ return this.where('type', type);
1579
+ }
1580
+ whereProviderContains(provider) {
1581
+ return this.whereContains('provider', provider);
1582
+ }
1583
+ whereActiveEquals(active) {
1584
+ return this.where('active', active);
1585
+ }
1586
+ whereIsExternalEquals(isExternal) {
1587
+ return this.where('is_external', isExternal);
1588
+ }
1589
+ }
1590
+ /**
1591
+ * Financial Request Query Builder
1592
+ */
1593
+ class FinancialRequestQueryBuilder extends QueryBuilder {
1594
+ constructor(resource, initialQuery) {
1595
+ super(initialQuery);
1596
+ this.resource = resource;
1597
+ }
1598
+ async execute() {
1599
+ return this.resource.query(this.getRawQuery());
1600
+ }
1601
+ whereStatusIn(statuses) {
1602
+ return this.whereIn('status', statuses);
1603
+ }
1604
+ whereTotalGreaterThan(amount) {
1605
+ return this.whereRange('total', amount, undefined);
1606
+ }
1607
+ whereTotalLessThan(amount) {
1608
+ return this.whereRange('total', undefined, amount);
1609
+ }
1610
+ whereMerchantIdEquals(merchantId) {
1611
+ return this.where('merchant_id', merchantId);
1612
+ }
1613
+ }
1614
+ /**
1615
+ * Webhook URL Query Builder
1616
+ */
1617
+ class WebhookUrlQueryBuilder extends QueryBuilder {
1618
+ constructor(resource, initialQuery) {
1619
+ super(initialQuery);
1620
+ this.resource = resource;
1621
+ }
1622
+ async execute() {
1623
+ return this.resource.query(this.getRawQuery());
1624
+ }
1625
+ whereEventEquals(event) {
1626
+ return this.where('event', event);
1627
+ }
1628
+ whereMerchantIdEquals(merchantId) {
1629
+ return this.where('merchant_id', merchantId);
1630
+ }
1631
+ whereOrgIdEquals(orgId) {
1632
+ return this.where('org_id', orgId);
1633
+ }
1634
+ whereUrlContains(url) {
1635
+ return this.whereContains('url', url);
1636
+ }
1637
+ }
1638
+ /**
1639
+ * Token Query Builder
1640
+ */
1641
+ class TokenQueryBuilder extends QueryBuilder {
1642
+ constructor(resource, initialQuery) {
1643
+ super(initialQuery);
1644
+ this.resource = resource;
1645
+ }
1646
+ async execute() {
1647
+ return this.resource.query(this.getRawQuery());
1648
+ }
1649
+ whereEnabledEquals(enabled) {
1650
+ return this.where('enabled', enabled);
1651
+ }
1652
+ whereKindIn(kinds) {
1653
+ return this.whereIn('kind', kinds);
1654
+ }
1655
+ whereUserIdEquals(userId) {
1656
+ return this.where('user_id', userId);
1657
+ }
1658
+ whereProviderEquals(provider) {
1659
+ return this.where('provider', provider);
1660
+ }
1661
+ }
1662
+ /**
1663
+ * Address Query Builder
1664
+ */
1665
+ class AddressQueryBuilder extends QueryBuilder {
1666
+ constructor(resource, initialQuery) {
1667
+ super(initialQuery);
1668
+ this.resource = resource;
1669
+ }
1670
+ async execute() {
1671
+ return this.resource.query(this.getRawQuery());
1672
+ }
1673
+ whereCountryEquals(country) {
1674
+ return this.where('country', country);
1675
+ }
1676
+ whereStateEquals(state) {
1677
+ return this.where('state', state);
1678
+ }
1679
+ whereCityContains(city) {
1680
+ return this.whereContains('city', city);
1681
+ }
1682
+ whereKindIn(kinds) {
1683
+ return this.whereIn('kind', kinds);
1684
+ }
1685
+ }
1686
+ /**
1687
+ * Currency Query Builder
1688
+ */
1689
+ class CurrencyQueryBuilder extends QueryBuilder {
1690
+ constructor(resource, initialQuery) {
1691
+ super(initialQuery);
1692
+ this.resource = resource;
1693
+ }
1694
+ async execute() {
1695
+ return this.resource.query(this.getRawQuery());
1696
+ }
1697
+ whereCodeIn(codes) {
1698
+ return this.whereIn('code', codes);
1699
+ }
1700
+ whereIsFloatEquals(isFloat) {
1701
+ return this.where('is_float', isFloat);
1702
+ }
1703
+ }
1704
+ /**
1705
+ * Exchange Rate Query Builder
1706
+ */
1707
+ class ExchangeRateQueryBuilder extends QueryBuilder {
1708
+ constructor(resource, initialQuery) {
1709
+ super(initialQuery);
1710
+ this.resource = resource;
1711
+ }
1712
+ async execute() {
1713
+ return this.resource.query(this.getRawQuery());
1714
+ }
1715
+ whereSourceIdEquals(sourceId) {
1716
+ return this.where('source_id', sourceId);
1717
+ }
1718
+ whereDestinationIdEquals(destinationId) {
1719
+ return this.where('destination_id', destinationId);
1720
+ }
1721
+ whereRateGreaterThan(rate) {
1722
+ return this.whereRange('rate', rate, undefined);
1723
+ }
1724
+ }
1725
+ /**
1726
+ * Fee Query Builder
1727
+ */
1728
+ class FeeQueryBuilder extends QueryBuilder {
1729
+ constructor(resource, initialQuery) {
1730
+ super(initialQuery);
1731
+ this.resource = resource;
1732
+ }
1733
+ async execute() {
1734
+ return this.resource.query(this.getRawQuery());
1735
+ }
1736
+ whereKindIn(kinds) {
1737
+ return this.whereIn('kind', kinds);
1738
+ }
1739
+ whereTotalGreaterThan(amount) {
1740
+ return this.whereRange('total', amount, undefined);
1741
+ }
1742
+ whereCurrencyCodeEquals(code) {
1743
+ return this.where('currency_code', code);
1744
+ }
1745
+ whereCompoundEquals(compound) {
1746
+ return this.where('compound', compound);
1747
+ }
1748
+ }
1749
+ /**
1750
+ * Payment Method Query Builder
1751
+ */
1752
+ class PaymentMethodQueryBuilder extends QueryBuilder {
1753
+ constructor(resource, initialQuery) {
1754
+ super(initialQuery);
1755
+ this.resource = resource;
1756
+ }
1757
+ async execute() {
1758
+ return this.resource.query(this.getRawQuery());
1759
+ }
1760
+ whereActiveEquals(active) {
1761
+ return this.where('active', active);
1762
+ }
1763
+ whereProviderEquals(provider) {
1764
+ return this.where('provider', provider);
1765
+ }
1766
+ whereCodeEquals(code) {
1767
+ return this.where('code', code);
1768
+ }
1769
+ }
1770
+ /**
1771
+ * Transaction Entry Query Builder
1772
+ */
1773
+ class TransactionEntryQueryBuilder extends QueryBuilder {
1774
+ constructor(resource, initialQuery) {
1775
+ super(initialQuery);
1776
+ this.resource = resource;
1777
+ }
1778
+ async execute() {
1779
+ return this.resource.query(this.getRawQuery());
1780
+ }
1781
+ whereAmountGreaterThan(amount) {
1782
+ return this.whereRange('amount', amount, undefined);
1783
+ }
1784
+ whereAmountLessThan(amount) {
1785
+ return this.whereRange('amount', undefined, amount);
1786
+ }
1787
+ whereTypeIn(types) {
1788
+ return this.whereIn('type', types);
1789
+ }
1790
+ whereTransactionIdEquals(transactionId) {
1791
+ return this.where('transaction_id', transactionId);
1792
+ }
1793
+ whereFinancialAccountIdEquals(accountId) {
1794
+ return this.where('financial_account_id', accountId);
1795
+ }
1796
+ }
1797
+ /**
1798
+ * KYC Query Builder
1799
+ * Provides a fluent interface for building complex KYC/legal request queries
1800
+ *
1801
+ * @example
1802
+ * const requests = await sdk.kyc.createQueryBuilder()
1803
+ * .whereStatus('pending')
1804
+ * .whereKind('document_submission')
1805
+ * .paginate(1, 20)
1806
+ * .execute();
1807
+ */
1808
+ class KycQueryBuilder extends QueryBuilder {
1809
+ constructor(resource, initialQuery) {
1810
+ super(initialQuery);
1811
+ this.resource = resource;
1812
+ }
1813
+ /**
1814
+ * Execute the query and return the results
1815
+ */
1816
+ async execute() {
1817
+ return this.resource.query(this.getRawQuery());
1818
+ }
1819
+ /**
1820
+ * Filter by KYC request status
1821
+ */
1822
+ whereStatus(status) {
1823
+ if (Array.isArray(status)) {
1824
+ return this.whereIn('status', status);
1825
+ }
1826
+ return this.where('status', status);
1827
+ }
1828
+ /**
1829
+ * Filter by KYC request kind/type
1830
+ */
1831
+ whereKind(kind) {
1832
+ if (Array.isArray(kind)) {
1833
+ return this.whereIn('kind', kind);
1834
+ }
1835
+ return this.where('kind', kind);
1836
+ }
1837
+ /**
1838
+ * Filter by subject ID
1839
+ */
1840
+ whereSubject(subjectId) {
1841
+ if (Array.isArray(subjectId)) {
1842
+ return this.whereIn('subject_id', subjectId);
1843
+ }
1844
+ return this.where('subject_id', subjectId);
1845
+ }
1846
+ /**
1847
+ * Filter by user ID
1848
+ */
1849
+ whereUser(userId) {
1850
+ if (Array.isArray(userId)) {
1851
+ return this.whereIn('user_id', userId);
1852
+ }
1853
+ return this.where('user_id', userId);
1854
+ }
1855
+ /**
1856
+ * Filter by creation date range
1857
+ */
1858
+ whereCreatedBetween(after, before) {
1859
+ return this.whereDateRange('inserted_at', after, before);
1860
+ }
1861
+ /**
1862
+ * Filter by update date range
1863
+ */
1864
+ whereUpdatedBetween(after, before) {
1865
+ return this.whereDateRange('updated_at', after, before);
1866
+ }
1867
+ }
1868
+
1869
+ /**
1870
+ * Resource-specific types and interfaces
1871
+ *
1872
+ * This file contains all filter parameters, list responses, and field type mappings
1873
+ * for each resource in the SDK. This provides clear IntelliSense and type safety.
1874
+ */
1875
+ // ============================================================================
1876
+ // FIELD TYPE MAPPINGS
1877
+ // ============================================================================
1878
+ // These define what operations are available on each field for type-safe querying
1879
+ /**
1880
+ * Order field types - defines what operations are available on each field
1881
+ */
1882
+ const ORDER_FIELD_TYPES = {
1883
+ id: 'number',
1884
+ reference_id: 'string',
1885
+ total: 'number',
1886
+ status: 'number',
1887
+ kind: 'number',
1888
+ status_on: 'number',
1889
+ uid: 'string',
1890
+ cart_id: 'number',
1891
+ currency_id: 'number',
1892
+ customer_id: 'number',
1893
+ payment_link_id: 'number',
1894
+ billing_plan_id: 'number',
1895
+ session_id: 'string',
1896
+ inserted_at: 'date',
1897
+ updated_at: 'date',
1898
+ };
1899
+ /**
1900
+ * Product field types
1901
+ */
1902
+ const PRODUCT_FIELD_TYPES = {
1903
+ id: 'number',
1904
+ title: 'string',
1905
+ teaser: 'string',
1906
+ price: 'number',
1907
+ permalink: 'string',
1908
+ image: 'string',
1909
+ status: 'number',
1910
+ public: 'boolean',
1911
+ unlimited: 'boolean',
1912
+ units_remaining: 'number',
1913
+ units_sold: 'number',
1914
+ rating_sum: 'number',
1915
+ rating_count: 'number',
1916
+ tag_ids: 'array',
1917
+ uid: 'string',
1918
+ category_id: 'number',
1919
+ currency_id: 'number',
1920
+ user_id: 'number',
1921
+ inserted_at: 'date',
1922
+ updated_at: 'date',
1923
+ };
1924
+ /**
1925
+ * User field types
1926
+ */
1927
+ const USER_FIELD_TYPES = {
1928
+ id: 'number',
1929
+ email: 'string',
1930
+ phone: 'string',
1931
+ first_name: 'string',
1932
+ last_name: 'string',
1933
+ username: 'string',
1934
+ status: 'number',
1935
+ kind: 'number',
1936
+ level: 'number',
1937
+ dob: 'number',
1938
+ sex: 'number',
1939
+ image: 'string',
1940
+ uid: 'string',
1941
+ organisation_id: 'number',
1942
+ role_id: 'number',
1943
+ inserted_at: 'date',
1944
+ updated_at: 'date',
1945
+ };
1946
+ /**
1947
+ * Merchant field types
1948
+ */
1949
+ const MERCHANT_FIELD_TYPES = {
1950
+ id: 'number',
1951
+ name: 'string',
1952
+ email: 'string',
1953
+ username: 'string',
1954
+ about: 'string',
1955
+ logo: 'string',
1956
+ sector: 'string',
1957
+ status: 'number',
1958
+ phone: 'string',
1959
+ business_type: 'string',
1960
+ theme_colour: 'string',
1961
+ uid: 'string',
1962
+ address_id: 'number',
1963
+ owner_id: 'number',
1964
+ domain_id: 'number',
1965
+ organisation_id: 'number',
1966
+ platform_fee_structure: 'number',
1967
+ provider_fee_structure: 'number',
1968
+ parent_merchant_id: 'number',
1969
+ inserted_at: 'date',
1970
+ updated_at: 'date',
1971
+ };
1972
+ /**
1973
+ * Category field types
1974
+ */
1975
+ const CATEGORY_FIELD_TYPES = {
1976
+ id: 'number',
1977
+ name: 'string',
1978
+ description: 'string',
1979
+ kind: 'number',
1980
+ kind_id: 'number',
1981
+ parent_id: 'number',
1982
+ uid: 'string',
1983
+ inserted_at: 'date',
1984
+ updated_at: 'date',
1985
+ };
1986
+ /**
1987
+ * Billing Plan field types
1988
+ */
1989
+ const BILLING_PLAN_FIELD_TYPES = {
1990
+ id: 'number',
1991
+ name: 'string',
1992
+ description: 'string',
1993
+ flat_rate: 'number',
1994
+ transaction_fee: 'number',
1995
+ transaction_percentage: 'number',
1996
+ transaction_percentage_additional: 'number',
1997
+ transaction_minimum_fee: 'number',
1998
+ minimum_fee: 'number',
1999
+ duration: 'number',
2000
+ status: 'number',
2001
+ kind: 'number',
2002
+ billing_cycle: 'number',
2003
+ trial_period: 'number',
2004
+ charge_strategy: 'number',
2005
+ auto_charge: 'boolean',
2006
+ public: 'boolean',
2007
+ payout_period: 'number',
2008
+ payout_value_limit: 'number',
2009
+ payout_percentage_limit: 'number',
2010
+ uid: 'string',
2011
+ currency_id: 'number',
2012
+ payment_provider_id: 'number',
2013
+ inserted_at: 'date',
2014
+ updated_at: 'date',
2015
+ };
2016
+ /**
2017
+ * Subscription field types
2018
+ */
2019
+ const SUBSCRIPTION_FIELD_TYPES = {
2020
+ id: 'number',
2021
+ status: 'number',
2022
+ kind: 'number',
2023
+ record_id: 'number',
2024
+ record: 'string',
2025
+ start_date: 'date',
2026
+ end_date: 'date',
2027
+ current_period_start: 'date',
2028
+ current_period_end: 'date',
2029
+ trial_end: 'date',
2030
+ canceled_at: 'date',
2031
+ uid: 'string',
2032
+ token: 'string',
2033
+ billing_plan_id: 'number',
2034
+ customer_id: 'number',
2035
+ inserted_at: 'date',
2036
+ updated_at: 'date',
2037
+ };
2038
+ /**
2039
+ * Payment Link field types
2040
+ */
2041
+ const PAYMENT_LINK_FIELD_TYPES = {
2042
+ id: 'number',
2043
+ uid: 'string',
2044
+ title: 'string',
2045
+ description: 'string',
2046
+ total: 'number',
2047
+ usage_limit: 'number',
2048
+ expires_at: 'date',
2049
+ status: 'number',
2050
+ kind: 'number',
2051
+ customer_id: 'number',
2052
+ currency_id: 'number',
2053
+ order_id: 'number',
2054
+ inserted_at: 'date',
2055
+ updated_at: 'date',
2056
+ };
2057
+ /**
2058
+ * Financial Account field types
2059
+ */
2060
+ const FINANCIAL_ACCOUNT_FIELD_TYPES = {
2061
+ id: 'number',
2062
+ name: 'string',
2063
+ type: 'string',
2064
+ provider: 'string',
2065
+ is_external: 'boolean',
2066
+ fingerprint: 'string',
2067
+ record: 'string',
2068
+ record_id: 'number',
2069
+ active: 'boolean',
2070
+ code: 'string',
2071
+ adapter: 'string',
2072
+ logo: 'string',
2073
+ website: 'string',
2074
+ inserted_at: 'date',
2075
+ updated_at: 'date',
2076
+ };
2077
+ /**
2078
+ * Financial Request field types
2079
+ */
2080
+ const FINANCIAL_REQUEST_FIELD_TYPES = {
2081
+ id: 'number',
2082
+ total: 'number',
2083
+ status: 'number',
2084
+ type: 'number',
2085
+ sub_type: 'number',
2086
+ fee_total: 'number',
2087
+ reference_id: 'string',
2088
+ reviewed_at: 'date',
2089
+ due_at: 'date',
2090
+ balance_on_request: 'number',
2091
+ source_id: 'number',
2092
+ destination_id: 'number',
2093
+ merchant_id: 'number',
2094
+ requester_id: 'number',
2095
+ reviewer_id: 'number',
2096
+ currency_id: 'number',
2097
+ evidence_file_id: 'number',
2098
+ inserted_at: 'date',
2099
+ updated_at: 'date',
2100
+ };
2101
+ /**
2102
+ * Webhook URL field types
2103
+ */
2104
+ const WEBHOOK_URL_FIELD_TYPES = {
2105
+ id: 'number',
2106
+ url: 'string',
2107
+ event: 'string',
2108
+ uid: 'string',
2109
+ merchant_id: 'number',
2110
+ org_id: 'number',
2111
+ inserted_at: 'date',
2112
+ updated_at: 'date',
2113
+ };
2114
+ /**
2115
+ * Token field types
2116
+ */
2117
+ const TOKEN_FIELD_TYPES = {
2118
+ id: 'number',
2119
+ public_key: 'string',
2120
+ title: 'string',
2121
+ provider: 'string',
2122
+ kind: 'number',
2123
+ enabled: 'boolean',
2124
+ expires: 'number',
2125
+ user_id: 'number',
2126
+ role_id: 'number',
2127
+ inserted_at: 'date',
2128
+ updated_at: 'date',
2129
+ };
2130
+ /**
2131
+ * Address field types
2132
+ */
2133
+ const ADDRESS_FIELD_TYPES = {
2134
+ id: 'number',
2135
+ hash: 'string',
2136
+ kind: 'number',
2137
+ kind_id: 'number',
2138
+ lang: 'number',
2139
+ lat: 'number',
2140
+ street: 'string',
2141
+ street_optional: 'string',
2142
+ city: 'string',
2143
+ state: 'string',
2144
+ country: 'string',
2145
+ region: 'string',
2146
+ town: 'string',
2147
+ inserted_at: 'date',
2148
+ updated_at: 'date',
2149
+ };
2150
+ /**
2151
+ * Currency field types
2152
+ */
2153
+ const CURRENCY_FIELD_TYPES = {
2154
+ id: 'number',
2155
+ code: 'string',
2156
+ flag: 'string',
2157
+ is_float: 'boolean',
2158
+ inserted_at: 'date',
2159
+ updated_at: 'date',
2160
+ };
2161
+ /**
2162
+ * Exchange Rate field types
2163
+ */
2164
+ const EXCHANGE_RATE_FIELD_TYPES = {
2165
+ id: 'number',
2166
+ source_id: 'number',
2167
+ destination_id: 'number',
2168
+ rate: 'number',
2169
+ expires: 'number',
2170
+ source: 'string',
2171
+ user_id: 'number',
2172
+ inserted_at: 'date',
2173
+ updated_at: 'date',
2174
+ };
2175
+ /**
2176
+ * Fee field types
2177
+ */
2178
+ const FEE_FIELD_TYPES = {
2179
+ id: 'number',
2180
+ title: 'string',
2181
+ total: 'number',
2182
+ unit: 'number',
2183
+ kind: 'number',
2184
+ priority: 'number',
2185
+ compound: 'boolean',
2186
+ fee_payer: 'number',
2187
+ currency_code: 'string',
2188
+ hash: 'string',
2189
+ fee_set_id: 'number',
2190
+ currency_id: 'number',
2191
+ user_id: 'number',
2192
+ inserted_at: 'date',
2193
+ updated_at: 'date',
2194
+ };
2195
+ /**
2196
+ * Payment Method field types
2197
+ */
2198
+ const PAYMENT_METHOD_FIELD_TYPES = {
2199
+ id: 'number',
2200
+ name: 'string',
2201
+ code: 'string',
2202
+ provider: 'string',
2203
+ active: 'boolean',
2204
+ payment_provider_id: 'number',
2205
+ financial_account_id: 'number',
2206
+ inserted_at: 'date',
2207
+ updated_at: 'date',
2208
+ };
2209
+ /**
2210
+ * Transaction Entry field types
2211
+ */
2212
+ const TRANSACTION_ENTRY_FIELD_TYPES = {
2213
+ id: 'number',
2214
+ amount: 'number',
2215
+ type: 'number',
2216
+ transaction_id: 'number',
2217
+ financial_account_id: 'number',
2218
+ inserted_at: 'date',
2219
+ updated_at: 'date',
2220
+ };
2221
+
2222
+ class MerchantsResource {
2223
+ constructor(client) {
2224
+ this.client = client;
2225
+ }
2226
+ /**
2227
+ * Convert internal merchant data (integers) to user-facing data (strings)
2228
+ */
2229
+ translateMerchantToUserFacing(internal) {
2230
+ return {
2231
+ ...internal,
2232
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'account'),
2233
+ platform_fee_structure: FeeStructureTranslator.toString(internal.platform_fee_structure),
2234
+ provider_fee_structure: FeeStructureTranslator.toString(internal.provider_fee_structure),
2235
+ };
2236
+ }
2237
+ /**
2238
+ * Convert user-facing merchant data (strings) to internal data (integers)
2239
+ */
2240
+ translateMerchantToInternal(userFacing) {
2241
+ const internal = { ...userFacing };
2242
+ if ('status' in userFacing && userFacing.status) {
2243
+ internal.status = typeof userFacing.status === 'string'
2244
+ ? StatusTranslator.toIntegerWithContext(userFacing.status, 'account')
2245
+ : userFacing.status;
2246
+ }
2247
+ if ('platform_fee_structure' in userFacing && userFacing.platform_fee_structure) {
2248
+ internal.platform_fee_structure = typeof userFacing.platform_fee_structure === 'string'
2249
+ ? FeeStructureTranslator.toInteger(userFacing.platform_fee_structure)
2250
+ : userFacing.platform_fee_structure;
2251
+ }
2252
+ if ('provider_fee_structure' in userFacing && userFacing.provider_fee_structure) {
2253
+ internal.provider_fee_structure = typeof userFacing.provider_fee_structure === 'string'
2254
+ ? FeeStructureTranslator.toInteger(userFacing.provider_fee_structure)
2255
+ : userFacing.provider_fee_structure;
2256
+ }
2257
+ return internal;
2258
+ }
2259
+ /**
2260
+ * Convert filter parameters (strings to integers where needed)
2261
+ */
2262
+ translateFilters(params) {
2263
+ if (!params)
2264
+ return params;
2265
+ const translated = { ...params };
2266
+ if (params.status && typeof params.status === 'string') {
2267
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'account');
2268
+ }
2269
+ if (params.platform_fee_structure && typeof params.platform_fee_structure === 'string') {
2270
+ translated.platform_fee_structure = FeeStructureTranslator.toInteger(params.platform_fee_structure);
2271
+ }
2272
+ if (params.provider_fee_structure && typeof params.provider_fee_structure === 'string') {
2273
+ translated.provider_fee_structure = FeeStructureTranslator.toInteger(params.provider_fee_structure);
2274
+ }
2275
+ return translated;
2276
+ }
2277
+ /**
2278
+ * List merchants with pagination and filtering
2279
+ */
2280
+ async list(params) {
2281
+ var _a;
2282
+ const translatedParams = this.translateFilters(params);
2283
+ const response = await this.client.get('/merchants', translatedParams);
2284
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
2285
+ const translatedEntries = response.result.entries.map(merchant => this.translateMerchantToUserFacing(merchant));
2286
+ return {
2287
+ state: response.state,
2288
+ result: {
2289
+ entries: translatedEntries,
2290
+ page_info: response.result.page_info
2291
+ }
2292
+ };
2293
+ }
2294
+ return {
2295
+ state: response.state,
2296
+ result: response.result
2297
+ };
2298
+ }
2299
+ /**
2300
+ * Get a specific merchant by ID
2301
+ */
2302
+ async get(id) {
2303
+ const response = await this.client.get(`/merchants/${id}`);
2304
+ if (response.result) {
2305
+ const translatedMerchant = this.translateMerchantToUserFacing(response.result);
2306
+ return {
2307
+ state: response.state,
2308
+ result: translatedMerchant
2309
+ };
2310
+ }
2311
+ return {
2312
+ state: response.state,
2313
+ result: response.result
2314
+ };
2315
+ }
2316
+ /**
2317
+ * Create a new merchant
2318
+ */
2319
+ async create(data) {
2320
+ const internalData = this.translateMerchantToInternal(data);
2321
+ const response = await this.client.post('/merchants', internalData);
2322
+ if (response.result) {
2323
+ const translatedMerchant = this.translateMerchantToUserFacing(response.result);
2324
+ return {
2325
+ state: response.state,
2326
+ result: translatedMerchant
2327
+ };
2328
+ }
2329
+ return {
2330
+ state: response.state,
2331
+ result: response.result
2332
+ };
2333
+ }
2334
+ /**
2335
+ * Update an existing merchant
2336
+ */
2337
+ async update(id, data) {
2338
+ const internalData = this.translateMerchantToInternal(data);
2339
+ const response = await this.client.put(`/merchants/${id}`, internalData);
2340
+ if (response.result) {
2341
+ const translatedMerchant = this.translateMerchantToUserFacing(response.result);
2342
+ return {
2343
+ state: response.state,
2344
+ result: translatedMerchant
2345
+ };
2346
+ }
2347
+ return {
2348
+ state: response.state,
2349
+ result: response.result
2350
+ };
2351
+ }
2352
+ /**
2353
+ * Get merchant account balances
2354
+ */
2355
+ async balances() {
2356
+ return this.client.post('/merchants/account/balances');
2357
+ }
2358
+ /**
2359
+ * Get merchant account limits
2360
+ */
2361
+ async limits() {
2362
+ return this.client.post('/merchants/account/limits');
2363
+ }
2364
+ /**
2365
+ * Get merchant subscription plan details
2366
+ */
2367
+ async subscription() {
2368
+ return this.client.post('/merchants/account/plan');
2369
+ }
2370
+ /**
2371
+ * Get list of merchant account invoices
2372
+ */
2373
+ async invoices() {
2374
+ return this.client.post('/merchants/account/invoices');
2375
+ }
2376
+ /**
2377
+ * Get a specific merchant invoice by ID
2378
+ */
2379
+ async invoice(invoiceId) {
2380
+ return this.client.post(`/merchants/account/invoice/${invoiceId}`);
2381
+ }
2382
+ /**
2383
+ * Query merchants with enhanced query support
2384
+ * @example
2385
+ * await merchants.query({ status: 'approved', sector: 'retail' })
2386
+ */
2387
+ async query(params) {
2388
+ var _a;
2389
+ const processedQuery = processQuery(params || {}, MERCHANT_FIELD_TYPES, { validate: true, context: 'account' });
2390
+ const response = await this.client.get('/merchants', processedQuery);
2391
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
2392
+ const translatedEntries = response.result.entries.map(m => this.translateMerchantToUserFacing(m));
2393
+ return {
2394
+ state: response.state,
2395
+ result: { entries: translatedEntries, page_info: response.result.page_info }
2396
+ };
2397
+ }
2398
+ return { state: response.state, result: response.result };
2399
+ }
2400
+ /**
2401
+ * Create a query builder for merchants
2402
+ * @example
2403
+ * await sdk.merchants.createQueryBuilder().whereStatus('approved').execute()
2404
+ */
2405
+ createQueryBuilder(initialQuery) {
2406
+ return new MerchantQueryBuilder(this, initialQuery);
2407
+ }
2408
+ }
2409
+
2410
+ class CategoriesResource {
2411
+ constructor(client) {
2412
+ this.client = client;
2413
+ }
2414
+ /**
2415
+ * Convert internal category data (integers) to user-facing data (strings)
2416
+ */
2417
+ translateCategoryToUserFacing(internal) {
2418
+ return {
2419
+ ...internal,
2420
+ kind: KindTranslator.toStringWithoutContext(internal.kind, 'product'),
2421
+ };
2422
+ }
2423
+ /**
2424
+ * Convert user-facing category data (strings) to internal data (integers)
2425
+ */
2426
+ translateCategoryToInternal(userFacing) {
2427
+ const internal = { ...userFacing };
2428
+ if ('kind' in userFacing && userFacing.kind) {
2429
+ if (typeof userFacing.kind === 'string') {
2430
+ internal.kind = KindTranslator.toIntegerWithContext(userFacing.kind, 'product');
2431
+ }
2432
+ else {
2433
+ internal.kind = userFacing.kind;
2434
+ }
2435
+ }
2436
+ return internal;
2437
+ }
2438
+ /**
2439
+ * Convert filter parameters (strings to integers where needed)
2440
+ */
2441
+ translateFilters(params) {
2442
+ if (!params)
2443
+ return params;
2444
+ const translated = { ...params };
2445
+ if (params.kind && typeof params.kind === 'string') {
2446
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'product');
2447
+ }
2448
+ return translated;
2449
+ }
2450
+ /**
2451
+ * List categories with pagination and filtering
2452
+ * Requires Client-Id header to be set in the configuration
2453
+ */
2454
+ async list(params) {
2455
+ var _a;
2456
+ const translatedParams = this.translateFilters(params);
2457
+ const response = await this.client.get('/categories', translatedParams);
2458
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
2459
+ const translatedEntries = response.result.entries.map(category => this.translateCategoryToUserFacing(category));
2460
+ return {
2461
+ state: response.state,
2462
+ result: {
2463
+ entries: translatedEntries,
2464
+ page_info: response.result.page_info
2465
+ }
2466
+ };
2467
+ }
2468
+ return {
2469
+ state: response.state,
2470
+ result: response.result
2471
+ };
2472
+ }
2473
+ /**
2474
+ * Get a specific category by ID
2475
+ * Requires Client-Id header to be set in the configuration
2476
+ */
2477
+ async get(id) {
2478
+ const response = await this.client.get(`/categories/${id}`);
2479
+ if (response.result) {
2480
+ const translatedCategory = this.translateCategoryToUserFacing(response.result);
2481
+ return {
2482
+ state: response.state,
2483
+ result: translatedCategory
2484
+ };
2485
+ }
2486
+ return {
2487
+ state: response.state,
2488
+ result: response.result
2489
+ };
2490
+ }
2491
+ /**
2492
+ * Create a new category
2493
+ * Requires Client-Id header to be set in the configuration
2494
+ */
2495
+ async create(data) {
2496
+ const internalData = this.translateCategoryToInternal(data);
2497
+ const response = await this.client.post('/categories', internalData);
2498
+ if (response.result) {
2499
+ const translatedCategory = this.translateCategoryToUserFacing(response.result);
2500
+ return {
2501
+ state: response.state,
2502
+ result: translatedCategory
2503
+ };
2504
+ }
2505
+ return {
2506
+ state: response.state,
2507
+ result: response.result
2508
+ };
2509
+ }
2510
+ /**
2511
+ * Update an existing category
2512
+ * Requires Client-Id header to be set in the configuration
2513
+ * Note: parent_id is immutable and cannot be changed after creation
2514
+ */
2515
+ async update(id, data) {
2516
+ const internalData = this.translateCategoryToInternal(data);
2517
+ const response = await this.client.put(`/categories/${id}`, internalData);
2518
+ if (response.result) {
2519
+ const translatedCategory = this.translateCategoryToUserFacing(response.result);
2520
+ return {
2521
+ state: response.state,
2522
+ result: translatedCategory
2523
+ };
2524
+ }
2525
+ return {
2526
+ state: response.state,
2527
+ result: response.result
2528
+ };
2529
+ }
2530
+ /**
2531
+ * Query categories with enhanced query support
2532
+ * @example
2533
+ * await categories.query({ kind: 'published', parent_id: null })
2534
+ */
2535
+ async query(params) {
2536
+ var _a;
2537
+ const processedQuery = processQuery(params || {}, CATEGORY_FIELD_TYPES, { validate: true });
2538
+ const translatedQuery = this.translateFilters(processedQuery);
2539
+ const response = await this.client.get('/categories', translatedQuery);
2540
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
2541
+ const translatedEntries = response.result.entries.map(c => this.translateCategoryToUserFacing(c));
2542
+ return {
2543
+ state: response.state,
2544
+ result: { entries: translatedEntries, page_info: response.result.page_info }
2545
+ };
2546
+ }
2547
+ return { state: response.state, result: response.result };
2548
+ }
2549
+ /**
2550
+ * Create a query builder for categories
2551
+ * @example
2552
+ * await sdk.categories.createQueryBuilder().whereKind('published').execute()
2553
+ */
2554
+ createQueryBuilder(initialQuery) {
2555
+ return new CategoryQueryBuilder(this, initialQuery);
2556
+ }
2557
+ }
2558
+
2559
+ class OrdersResource {
2560
+ constructor(client) {
2561
+ this.client = client;
2562
+ }
2563
+ /**
2564
+ * Convert internal order data (integers) to user-facing data (strings)
2565
+ */
2566
+ translateOrderToUserFacing(internal) {
2567
+ const result = {
2568
+ ...internal,
2569
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'order'),
2570
+ kind: KindTranslator.toStringWithoutContext(internal.kind, 'order'),
2571
+ };
2572
+ // Translate nested merchant if present
2573
+ if (internal.merchant) {
2574
+ result.merchant = this.translateMerchantToUserFacing(internal.merchant);
2575
+ }
2576
+ return result;
2577
+ }
2578
+ /**
2579
+ * Convert internal merchant data to user-facing merchant
2580
+ */
2581
+ translateMerchantToUserFacing(internal) {
2582
+ return {
2583
+ ...internal,
2584
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'account'),
2585
+ platform_fee_structure: FeeStructureTranslator.toString(internal.platform_fee_structure),
2586
+ provider_fee_structure: FeeStructureTranslator.toString(internal.provider_fee_structure),
2587
+ };
2588
+ }
2589
+ /**
2590
+ * Convert filter parameters (strings to integers where needed)
2591
+ * @deprecated This method is no longer needed as processQuery handles translation
2592
+ */
2593
+ translateFilters(params) {
2594
+ if (!params)
2595
+ return params;
2596
+ const translated = { ...params };
2597
+ if (params.status && typeof params.status === 'string') {
2598
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'order');
2599
+ }
2600
+ if (params.kind && typeof params.kind === 'string') {
2601
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'order');
2602
+ }
2603
+ return translated;
2604
+ }
2605
+ /**
2606
+ * Convert status update data (strings to integers where needed)
2607
+ */
2608
+ translateStatusUpdate(data) {
2609
+ const internal = { ...data };
2610
+ if (data.status && typeof data.status === 'string') {
2611
+ internal.status = StatusTranslator.toIntegerWithContext(data.status, 'order');
2612
+ }
2613
+ return internal;
2614
+ }
2615
+ /**
2616
+ * Create a new order
2617
+ * Requires Client-Id header to be set in the configuration
2618
+ */
2619
+ async create(data) {
2620
+ return this.client.post('/orders', data);
2621
+ }
2622
+ /**
2623
+ * Get order details by ID
2624
+ * Requires Client-Id header to be set in the configuration
2625
+ */
2626
+ async get(id) {
2627
+ const response = await this.client.get(`/orders/${id}`);
2628
+ if (response.result) {
2629
+ const translatedOrder = this.translateOrderToUserFacing(response.result);
2630
+ return {
2631
+ state: response.state,
2632
+ result: translatedOrder
2633
+ };
2634
+ }
2635
+ return {
2636
+ state: response.state,
2637
+ result: response.result
2638
+ };
2639
+ }
2640
+ /**
2641
+ * Update order status
2642
+ * Requires Client-Id header to be set in the configuration
2643
+ */
2644
+ async update(id, data) {
2645
+ const internalData = this.translateStatusUpdate(data);
2646
+ const response = await this.client.put(`/orders/${id}`, internalData);
2647
+ if (response.result) {
2648
+ const translatedOrder = this.translateOrderToUserFacing(response.result);
2649
+ return {
2650
+ state: response.state,
2651
+ result: translatedOrder
2652
+ };
2653
+ }
2654
+ return {
2655
+ state: response.state,
2656
+ result: response.result
2657
+ };
2658
+ }
2659
+ /**
2660
+ * Delete an order
2661
+ * Requires Client-Id header to be set in the configuration
2662
+ */
2663
+ async delete(id) {
2664
+ return this.client.delete(`/orders/${id}`);
2665
+ }
2666
+ /**
2667
+ * Get order status (public endpoint - no auth required)
2668
+ */
2669
+ async getStatus(id) {
2670
+ const response = await this.client.get(`/orders/status/${id}`);
2671
+ if (response.result) {
2672
+ const translatedOrder = this.translateOrderToUserFacing(response.result);
2673
+ return {
2674
+ state: response.state,
2675
+ result: translatedOrder
2676
+ };
2677
+ }
2678
+ return {
2679
+ state: response.state,
2680
+ result: response.result
2681
+ };
2682
+ }
2683
+ /**
2684
+ * Get order list with pagination and filtering
2685
+ * Supports filtering by any database field
2686
+ * Requires Client-Id header to be set in the configuration
2687
+ */
2688
+ async list(params) {
2689
+ var _a;
2690
+ const translatedParams = this.translateFilters(params);
2691
+ const response = await this.client.get('/orders', translatedParams);
2692
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
2693
+ const translatedEntries = response.result.entries.map(order => this.translateOrderToUserFacing(order));
2694
+ return {
2695
+ state: response.state,
2696
+ result: {
2697
+ entries: translatedEntries,
2698
+ page_info: response.result.page_info
2699
+ }
2700
+ };
2701
+ }
2702
+ return {
2703
+ state: response.state,
2704
+ result: response.result
2705
+ };
2706
+ }
2707
+ /**
2708
+ * List orders with enhanced query support
2709
+ * Supports filtering by any database field using the new query system
2710
+ * Requires Client-Id header to be set in the configuration
2711
+ *
2712
+ * @example
2713
+ * // Simple queries
2714
+ * await orders.query({ status: 'confirmed', kind: 'online' })
2715
+ *
2716
+ * // Array queries (IN operations)
2717
+ * await orders.query({ id: [1, 2, 3], status: ['confirmed', 'shipped'] })
2718
+ *
2719
+ * // Range queries
2720
+ * await orders.query({ total: { min: 100, max: 1000 } })
2721
+ *
2722
+ * // String searches
2723
+ * await orders.query({ reference_id: { contains: 'ORDER-2024' } })
2724
+ *
2725
+ * // Date range queries
2726
+ * await orders.query({ inserted_at: { after: '2024-01-01', before: '2024-12-31' } })
2727
+ *
2728
+ * // Combined queries
2729
+ * await orders.query({
2730
+ * status: 'confirmed',
2731
+ * total: { min: 50 },
2732
+ * inserted_at: { after: '2024-01-01' },
2733
+ * page: 1,
2734
+ * page_size: 20
2735
+ * })
2736
+ */
2737
+ async query(params) {
2738
+ var _a;
2739
+ // Process the query through the transformation system with validation and translation
2740
+ const processedQuery = processQuery(params || {}, ORDER_FIELD_TYPES, { validate: true, context: 'order' });
2741
+ const response = await this.client.get('/orders', processedQuery);
2742
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
2743
+ const translatedEntries = response.result.entries.map(order => this.translateOrderToUserFacing(order));
2744
+ return {
2745
+ state: response.state,
2746
+ result: {
2747
+ entries: translatedEntries,
2748
+ page_info: response.result.page_info
2749
+ }
2750
+ };
2751
+ }
2752
+ return {
2753
+ state: response.state,
2754
+ result: response.result
2755
+ };
2756
+ }
2757
+ /**
2758
+ * Create a query builder for orders
2759
+ * Provides a fluent interface for building complex queries
2760
+ *
2761
+ * @example
2762
+ * const orders = await sdk.orders.createQueryBuilder()
2763
+ * .whereStatus('confirmed')
2764
+ * .whereTotalRange(100, 1000)
2765
+ * .whereReferenceContains('ORDER-2024')
2766
+ * .paginate(1, 20)
2767
+ * .orderBy('inserted_at', 'desc')
2768
+ * .execute();
2769
+ */
2770
+ createQueryBuilder(initialQuery) {
2771
+ return new OrderQueryBuilder(this, initialQuery);
2772
+ }
2773
+ }
2774
+
2775
+ class ProductsResource {
2776
+ constructor(client) {
2777
+ this.client = client;
2778
+ }
2779
+ /**
2780
+ * Convert internal product data (integers) to user-facing data (strings)
2781
+ */
2782
+ translateProductToUserFacing(internal) {
2783
+ return {
2784
+ ...internal,
2785
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'product'),
2786
+ };
2787
+ }
2788
+ /**
2789
+ * Convert user-facing product data (strings) to internal data (integers)
2790
+ */
2791
+ translateProductToInternal(userFacing) {
2792
+ const internal = { ...userFacing };
2793
+ if ('status' in userFacing && userFacing.status) {
2794
+ internal.status = typeof userFacing.status === 'string'
2795
+ ? StatusTranslator.toIntegerWithContext(userFacing.status, 'product')
2796
+ : userFacing.status;
2797
+ }
2798
+ return internal;
2799
+ }
2800
+ /**
2801
+ * Convert filter parameters (strings to integers where needed)
2802
+ */
2803
+ translateFilters(params) {
2804
+ if (!params)
2805
+ return params;
2806
+ const translated = { ...params };
2807
+ if (params.status && typeof params.status === 'string') {
2808
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'product');
2809
+ }
2810
+ return translated;
2811
+ }
2812
+ /**
2813
+ * List products with pagination and filtering
2814
+ * Requires Client-Id header to be set in the configuration
2815
+ */
2816
+ async list(params) {
2817
+ var _a;
2818
+ const translatedParams = this.translateFilters(params);
2819
+ const response = await this.client.get('/products', translatedParams);
2820
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
2821
+ const translatedEntries = response.result.entries.map(product => this.translateProductToUserFacing(product));
2822
+ return {
2823
+ state: response.state,
2824
+ result: {
2825
+ entries: translatedEntries,
2826
+ page_info: response.result.page_info
2827
+ }
2828
+ };
2829
+ }
2830
+ return {
2831
+ state: response.state,
2832
+ result: response.result
2833
+ };
2834
+ }
2835
+ /**
2836
+ * Get a specific product by ID
2837
+ * Requires Client-Id header to be set in the configuration
2838
+ */
2839
+ async get(id) {
2840
+ const response = await this.client.get(`/products/${id}`);
2841
+ if (response.result) {
2842
+ const translatedProduct = this.translateProductToUserFacing(response.result);
2843
+ return {
2844
+ state: response.state,
2845
+ result: translatedProduct
2846
+ };
2847
+ }
2848
+ return {
2849
+ state: response.state,
2850
+ result: response.result
2851
+ };
2852
+ }
2853
+ /**
2854
+ * Create a new product
2855
+ * Requires Client-Id header to be set in the configuration
2856
+ */
2857
+ async create(data) {
2858
+ const internalData = this.translateProductToInternal(data);
2859
+ const response = await this.client.post('/products', internalData);
2860
+ if (response.result) {
2861
+ const translatedProduct = this.translateProductToUserFacing(response.result);
2862
+ return {
2863
+ state: response.state,
2864
+ result: translatedProduct
2865
+ };
2866
+ }
2867
+ return {
2868
+ state: response.state,
2869
+ result: response.result
2870
+ };
2871
+ }
2872
+ /**
2873
+ * Update an existing product
2874
+ * Requires Client-Id header to be set in the configuration
2875
+ */
2876
+ async update(id, data) {
2877
+ const internalData = this.translateProductToInternal(data);
2878
+ const response = await this.client.put(`/products/${id}`, internalData);
2879
+ if (response.result) {
2880
+ const translatedProduct = this.translateProductToUserFacing(response.result);
2881
+ return {
2882
+ state: response.state,
2883
+ result: translatedProduct
2884
+ };
2885
+ }
2886
+ return {
2887
+ state: response.state,
2888
+ result: response.result
2889
+ };
2890
+ }
2891
+ /**
2892
+ * Delete a product
2893
+ * Requires Client-Id header to be set in the configuration
2894
+ */
2895
+ async delete(id) {
2896
+ return this.client.delete(`/products/${id}`);
2897
+ }
2898
+ /**
2899
+ * List products with enhanced query support
2900
+ * Supports filtering by any database field using the new query system
2901
+ * Requires Client-Id header to be set in the configuration
2902
+ *
2903
+ * @example
2904
+ * // Simple queries
2905
+ * await products.query({ status: 'published', public: true })
2906
+ *
2907
+ * // Array queries (IN operations)
2908
+ * await products.query({ category_id: [1, 2, 3], status: ['published', 'draft'] })
2909
+ *
2910
+ * // Range queries
2911
+ * await products.query({ price: { min: 10, max: 100 } })
2912
+ *
2913
+ * // String searches
2914
+ * await products.query({ title: { contains: 'shirt' } })
2915
+ *
2916
+ * // Combined queries
2917
+ * await products.query({
2918
+ * status: 'published',
2919
+ * price: { min: 20 },
2920
+ * public: true,
2921
+ * page: 1,
2922
+ * page_size: 20
2923
+ * })
2924
+ */
2925
+ async query(params) {
2926
+ var _a;
2927
+ // Process the query through the transformation system with validation and translation
2928
+ const processedQuery = processQuery(params || {}, PRODUCT_FIELD_TYPES, { validate: true, context: 'product' });
2929
+ const response = await this.client.get('/products', processedQuery);
2930
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
2931
+ const translatedEntries = response.result.entries.map(product => this.translateProductToUserFacing(product));
2932
+ return {
2933
+ state: response.state,
2934
+ result: {
2935
+ entries: translatedEntries,
2936
+ page_info: response.result.page_info
2937
+ }
2938
+ };
2939
+ }
2940
+ return {
2941
+ state: response.state,
2942
+ result: response.result
2943
+ };
2944
+ }
2945
+ /**
2946
+ * Create a query builder for products
2947
+ * Provides a fluent interface for building complex queries
2948
+ *
2949
+ * @example
2950
+ * const products = await sdk.products.createQueryBuilder()
2951
+ * .whereStatus('published')
2952
+ * .wherePriceRange(10, 100)
2953
+ * .whereTitleContains('shirt')
2954
+ * .wherePublic(true)
2955
+ * .paginate(1, 20)
2956
+ * .execute();
2957
+ */
2958
+ createQueryBuilder(initialQuery) {
2959
+ return new ProductQueryBuilder(this, initialQuery);
2960
+ }
2961
+ }
2962
+
2963
+ class BillingPlansResource {
2964
+ constructor(client) {
2965
+ this.client = client;
2966
+ }
2967
+ /**
2968
+ * Convert internal billing plan data (integers) to user-facing data (strings)
2969
+ */
2970
+ translateToUserFacing(internal) {
2971
+ return {
2972
+ ...internal,
2973
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'billing_plan'),
2974
+ kind: KindTranslator.toStringWithoutContext(internal.kind, 'billing_plan'),
2975
+ };
2976
+ }
2977
+ /**
2978
+ * Convert filter parameters (strings to integers where needed)
2979
+ */
2980
+ translateFilters(params) {
2981
+ if (!params)
2982
+ return params;
2983
+ const translated = { ...params };
2984
+ if (params.status && typeof params.status === 'string') {
2985
+ translated.status = StatusTranslator.toInteger(params.status);
2986
+ }
2987
+ if (params.kind && typeof params.kind === 'string') {
2988
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'billing_plan');
2989
+ }
2990
+ return translated;
2991
+ }
2992
+ /**
2993
+ * Translate billing plan data for API (contextual strings to integers)
2994
+ */
2995
+ translateToInternal(data) {
2996
+ const internal = { ...data };
2997
+ // Translate kind if present and is a string
2998
+ if ('kind' in data && data.kind && typeof data.kind === 'string') {
2999
+ internal.kind = KindTranslator.toIntegerWithContext(data.kind, 'billing_plan');
3000
+ }
3001
+ // Translate status if present and is a string (for updates)
3002
+ if ('status' in data && data.status && typeof data.status === 'string') {
3003
+ internal.status = StatusTranslator.toInteger(data.status);
3004
+ }
3005
+ return internal;
3006
+ }
3007
+ /**
3008
+ * List billing plans with pagination and filtering
3009
+ * Requires Client-Id header to be set in the configuration
3010
+ */
3011
+ async list(params) {
3012
+ var _a;
3013
+ const translatedParams = this.translateFilters(params);
3014
+ const response = await this.client.get('/billing_plans', translatedParams);
3015
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
3016
+ const translatedEntries = response.result.entries.map(plan => this.translateToUserFacing(plan));
3017
+ return {
3018
+ state: response.state,
3019
+ result: {
3020
+ entries: translatedEntries,
3021
+ page_info: response.result.page_info
3022
+ }
3023
+ };
3024
+ }
3025
+ return {
3026
+ state: response.state,
3027
+ result: response.result
3028
+ };
3029
+ }
3030
+ /**
3031
+ * Get a specific billing plan by ID
3032
+ * Requires Client-Id header to be set in the configuration
3033
+ */
3034
+ async get(id) {
3035
+ const response = await this.client.get(`/billing_plans/${id}`);
3036
+ if (response.result) {
3037
+ const translatedPlan = this.translateToUserFacing(response.result);
3038
+ return {
3039
+ state: response.state,
3040
+ result: translatedPlan
3041
+ };
3042
+ }
3043
+ return {
3044
+ state: response.state,
3045
+ result: response.result
3046
+ };
3047
+ }
3048
+ /**
3049
+ * Create a new billing plan
3050
+ * Requires Client-Id header to be set in the configuration
3051
+ */
3052
+ async create(data) {
3053
+ const internalData = this.translateToInternal(data);
3054
+ const response = await this.client.post('/billing_plans', internalData);
3055
+ if (response.result) {
3056
+ const translatedPlan = this.translateToUserFacing(response.result);
3057
+ return {
3058
+ state: response.state,
3059
+ result: translatedPlan
3060
+ };
3061
+ }
3062
+ return {
3063
+ state: response.state,
3064
+ result: response.result
3065
+ };
3066
+ }
3067
+ /**
3068
+ * Update an existing billing plan
3069
+ * Requires Client-Id header to be set in the configuration
3070
+ */
3071
+ async update(id, data) {
3072
+ const internalData = this.translateToInternal(data);
3073
+ const response = await this.client.put(`/billing_plans/${id}`, internalData);
3074
+ if (response.result) {
3075
+ const translatedPlan = this.translateToUserFacing(response.result);
3076
+ return {
3077
+ state: response.state,
3078
+ result: translatedPlan
3079
+ };
3080
+ }
3081
+ return {
3082
+ state: response.state,
3083
+ result: response.result
3084
+ };
3085
+ }
3086
+ /**
3087
+ * Delete a billing plan
3088
+ * Requires Client-Id header to be set in the configuration
3089
+ */
3090
+ async delete(id) {
3091
+ return this.client.delete(`/billing_plans/${id}`);
3092
+ }
3093
+ /**
3094
+ * Query billing plans with enhanced query support
3095
+ * @example
3096
+ * await billingPlans.query({ kind: 'subscription', public: true })
3097
+ */
3098
+ async query(params) {
3099
+ var _a;
3100
+ const processedQuery = processQuery(params || {}, BILLING_PLAN_FIELD_TYPES, { validate: true, context: 'billing_plan' });
3101
+ const response = await this.client.get('/billing_plans', processedQuery);
3102
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
3103
+ const translatedEntries = response.result.entries.map(plan => this.translateToUserFacing(plan));
3104
+ return {
3105
+ state: response.state,
3106
+ result: {
3107
+ entries: translatedEntries,
3108
+ page_info: response.result.page_info
3109
+ }
3110
+ };
3111
+ }
3112
+ return {
3113
+ state: response.state,
3114
+ result: response.result
3115
+ };
3116
+ }
3117
+ /**
3118
+ * Create a query builder for billing plans
3119
+ * @example
3120
+ * await sdk.billingPlans.createQueryBuilder().whereKind('subscription').execute()
3121
+ */
3122
+ createQueryBuilder(initialQuery) {
3123
+ return new BillingPlanQueryBuilder(this, initialQuery);
3124
+ }
3125
+ }
3126
+
3127
+ class SubscriptionsResource {
3128
+ constructor(client) {
3129
+ this.client = client;
3130
+ }
3131
+ /**
3132
+ * Convert internal subscription data (integers) to user-facing data (strings)
3133
+ */
3134
+ translateToUserFacing(internal) {
3135
+ const result = {
3136
+ ...internal,
3137
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'billing_subscription'),
3138
+ kind: KindTranslator.toStringWithoutContext(internal.kind, 'billing_subscription'),
3139
+ };
3140
+ // Translate nested billing plan if present
3141
+ if (internal.billing_plan) {
3142
+ result.billing_plan = this.translateBillingPlanToUserFacing(internal.billing_plan);
3143
+ }
3144
+ return result;
3145
+ }
3146
+ /**
3147
+ * Convert internal billing plan data to user-facing billing plan
3148
+ */
3149
+ translateBillingPlanToUserFacing(internal) {
3150
+ return {
3151
+ ...internal,
3152
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'billing_plan'),
3153
+ kind: KindTranslator.toStringWithoutContext(internal.kind, 'billing_plan'),
3154
+ };
3155
+ }
3156
+ /**
3157
+ * Convert filter parameters (strings to integers where needed)
3158
+ * @deprecated This method is no longer needed as processQuery handles translation
3159
+ */
3160
+ translateFilters(params) {
3161
+ if (!params)
3162
+ return params;
3163
+ const translated = { ...params };
3164
+ if (params.status && typeof params.status === 'string') {
3165
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'billing_subscription');
3166
+ }
3167
+ return translated;
3168
+ }
3169
+ /**
3170
+ * Translate subscription data for API (contextual strings to integers)
3171
+ */
3172
+ translateToInternal(data) {
3173
+ const internal = { ...data };
3174
+ // Translate status if present and is a string
3175
+ if (data.status && typeof data.status === 'string') {
3176
+ internal.status = StatusTranslator.toIntegerWithContext(data.status, 'billing_subscription');
3177
+ }
3178
+ // Translate kind if present and is a string
3179
+ if (data.kind && typeof data.kind === 'string') {
3180
+ internal.kind = KindTranslator.toInteger(data.kind);
3181
+ }
3182
+ return internal;
3183
+ }
3184
+ /**
3185
+ * List billing subscriptions with pagination and filtering
3186
+ * Requires Client-Id header to be set in the configuration
3187
+ */
3188
+ async list(params) {
3189
+ var _a;
3190
+ const translatedParams = this.translateFilters(params);
3191
+ const response = await this.client.get('/billing_subscriptions', translatedParams);
3192
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
3193
+ const translatedEntries = response.result.entries.map(sub => this.translateToUserFacing(sub));
3194
+ return {
3195
+ state: response.state,
3196
+ result: {
3197
+ entries: translatedEntries,
3198
+ page_info: response.result.page_info
3199
+ }
3200
+ };
3201
+ }
3202
+ return {
3203
+ state: response.state,
3204
+ result: response.result
3205
+ };
3206
+ }
3207
+ /**
3208
+ * Gets a billing subscription by ID
3209
+ * Requires Client-Id header to be set in the configuration
3210
+ */
3211
+ async get(id) {
3212
+ const response = await this.client.get(`/billing_subscriptions/${id}`);
3213
+ if (response.result) {
3214
+ const translatedSub = this.translateToUserFacing(response.result);
3215
+ return {
3216
+ state: response.state,
3217
+ result: translatedSub
3218
+ };
3219
+ }
3220
+ return {
3221
+ state: response.state,
3222
+ result: response.result
3223
+ };
3224
+ }
3225
+ /**
3226
+ * Create a new subscription
3227
+ * Requires Client-Id header to be set in the configuration
3228
+ */
3229
+ async create(data) {
3230
+ const internalData = this.translateToInternal(data);
3231
+ const response = await this.client.post('/billing_subscriptions', internalData);
3232
+ if (response.result) {
3233
+ const translatedSub = this.translateToUserFacing(response.result);
3234
+ return {
3235
+ state: response.state,
3236
+ result: translatedSub
3237
+ };
3238
+ }
3239
+ return {
3240
+ state: response.state,
3241
+ result: response.result
3242
+ };
3243
+ }
3244
+ /**
3245
+ * Delete a subscription
3246
+ * Requires Client-Id header to be set in the configuration
3247
+ */
3248
+ async delete(id) {
3249
+ return this.client.delete(`/billing_subscriptions/${id}`);
3250
+ }
3251
+ /**
3252
+ * Create a subscription payment link
3253
+ * Requires Client-Id header to be set in the configuration
3254
+ */
3255
+ async createLink(data) {
3256
+ return this.client.post('/billing_subscriptions/link', { ...data, plan_id: data.plan_uid });
3257
+ }
3258
+ /**
3259
+ * Charge an existing subscription
3260
+ * Requires Client-Id header to be set in the configuration
3261
+ */
3262
+ async charge(uid, data) {
3263
+ return this.client.post(`/billing_subscriptions/${uid}/charge`, data);
3264
+ }
3265
+ /**
3266
+ * Record usage for a subscription (for usage-based billing)
3267
+ * Requires Client-Id header to be set in the configuration
3268
+ */
3269
+ async usage(uid, data) {
3270
+ return this.client.post(`/billing_subscriptions/${uid}/usage`, data);
3271
+ }
3272
+ /**
3273
+ * Get subscription billing periods
3274
+ * Requires Client-Id header to be set in the configuration
3275
+ */
3276
+ async getPeriods(uid, params) {
3277
+ return this.client.get(`/billing_subscriptions/${uid}/periods`, params);
3278
+ }
3279
+ /**
3280
+ * Cancel a subscription
3281
+ * Requires Client-Id header to be set in the configuration
3282
+ */
3283
+ async cancel(uid, code) {
3284
+ return this.client.post(`/billing_subscriptions/${uid}/cancel/${code}`);
3285
+ }
3286
+ /**
3287
+ * Query subscriptions with enhanced query support
3288
+ * @example
3289
+ * await subscriptions.query({ status: 'active', billing_plan_id: 123 })
3290
+ */
3291
+ async query(params) {
3292
+ const processedQuery = processQuery(params || {}, SUBSCRIPTION_FIELD_TYPES, { validate: true, context: 'billing_subscription' });
3293
+ return this.client.get('/billing_subscriptions', processedQuery);
3294
+ }
3295
+ /**
3296
+ * Create a query builder for subscriptions
3297
+ * @example
3298
+ * await sdk.subscriptions.createQueryBuilder().whereStatus('active').execute()
3299
+ */
3300
+ createQueryBuilder(initialQuery) {
3301
+ return new SubscriptionQueryBuilder(this, initialQuery);
3302
+ }
3303
+ }
3304
+
3305
+ class UsersResource {
3306
+ constructor(client) {
3307
+ this.client = client;
3308
+ }
3309
+ /**
3310
+ * Convert internal user data (integers) to user-facing data (strings)
3311
+ */
3312
+ translateUserToUserFacing(internal) {
3313
+ return {
3314
+ ...internal,
3315
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'account'),
3316
+ kind: KindTranslator.toStringWithoutContext(internal.kind, 'user'),
3317
+ };
3318
+ }
3319
+ /**
3320
+ * Convert user-facing user data (strings) to internal data (integers)
3321
+ */
3322
+ translateUserToInternal(userFacing) {
3323
+ const internal = { ...userFacing };
3324
+ if ('status' in userFacing && userFacing.status) {
3325
+ if (typeof userFacing.status === 'string') {
3326
+ internal.status = StatusTranslator.toIntegerWithContext(userFacing.status, 'account');
3327
+ }
3328
+ else {
3329
+ internal.status = userFacing.status;
3330
+ }
3331
+ }
3332
+ if ('kind' in userFacing && userFacing.kind) {
3333
+ if (typeof userFacing.kind === 'string') {
3334
+ internal.kind = KindTranslator.toIntegerWithContext(userFacing.kind, 'user');
3335
+ }
3336
+ else {
3337
+ internal.kind = userFacing.kind;
3338
+ }
3339
+ }
3340
+ return internal;
3341
+ }
3342
+ /**
3343
+ * Convert filter parameters (strings to integers where needed)
3344
+ */
3345
+ translateFilters(params) {
3346
+ if (!params)
3347
+ return params;
3348
+ const translated = { ...params };
3349
+ if (params.status && typeof params.status === 'string') {
3350
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'account');
3351
+ }
3352
+ if (params.kind && typeof params.kind === 'string') {
3353
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'user');
3354
+ }
3355
+ return translated;
3356
+ }
3357
+ /**
3358
+ * List users with pagination and filtering
3359
+ * Requires Client-Id header to be set in the configuration
3360
+ */
3361
+ async list(params) {
3362
+ const translatedParams = this.translateFilters(params);
3363
+ return this.client.get('/users', translatedParams);
3364
+ }
3365
+ /**
3366
+ * Get a specific user by ID
3367
+ * Requires Client-Id header to be set in the configuration
3368
+ */
3369
+ async get(id) {
3370
+ return this.client.get(`/users/${id}`);
3371
+ }
3372
+ /**
3373
+ * Create a new user
3374
+ * Requires Client-Id header to be set in the configuration
3375
+ */
3376
+ async create(data) {
3377
+ const internalData = this.translateUserToInternal(data);
3378
+ return this.client.post('/users', internalData);
3379
+ }
3380
+ /**
3381
+ * Update an existing user
3382
+ * Requires Client-Id header to be set in the configuration
3383
+ */
3384
+ async update(id, data) {
3385
+ const translatedData = this.translateUserToInternal(data);
3386
+ return this.client.put(`/users/${id}`, translatedData);
3387
+ }
3388
+ /**
3389
+ * Delete a user
3390
+ * Requires Client-Id header to be set in the configuration
3391
+ */
3392
+ async delete(id) {
3393
+ return this.client.delete(`/users/${id}`);
3394
+ }
3395
+ /**
3396
+ * Query users with enhanced query support
3397
+ * @example
3398
+ * await users.query({ status: 'approved', level: { min: 5 } })
3399
+ */
3400
+ async query(params) {
3401
+ var _a;
3402
+ const processedQuery = processQuery(params || {}, USER_FIELD_TYPES, { validate: true });
3403
+ const translatedQuery = this.translateFilters(processedQuery);
3404
+ const response = await this.client.get('/users', translatedQuery);
3405
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
3406
+ const translatedEntries = response.result.entries.map(user => this.translateUserToUserFacing(user));
3407
+ return {
3408
+ state: response.state,
3409
+ result: { entries: translatedEntries, page_info: response.result.page_info }
3410
+ };
3411
+ }
3412
+ return { state: response.state, result: response.result };
3413
+ }
3414
+ /**
3415
+ * Create a query builder for users
3416
+ * @example
3417
+ * await sdk.users.createQueryBuilder().whereStatus('approved').execute()
3418
+ */
3419
+ createQueryBuilder(initialQuery) {
3420
+ return new UserQueryBuilder(this, initialQuery);
3421
+ }
3422
+ }
3423
+
3424
+ class PublicResource {
3425
+ constructor(client) {
3426
+ this.client = client;
3427
+ }
3428
+ /**
3429
+ * Get public information about a merchant by username or cname
3430
+ */
3431
+ async getMerchant(params) {
3432
+ return this.client.get(`/public/m`, params);
3433
+ }
3434
+ /**
3435
+ * Get merchant fees (public endpoint - no auth required)
3436
+ */
3437
+ async getMerchantFees(merchantUsername, params) {
3438
+ return this.client.get(`/public/m/${merchantUsername}/fees`, params);
3439
+ }
3440
+ /**
3441
+ * Get merchant products (public endpoint - no auth required)
3442
+ */
3443
+ async getMerchantProducts(merchantUsername, params) {
3444
+ return this.client.get(`/public/m/${merchantUsername}/products`, params);
3445
+ }
3446
+ }
3447
+
3448
+ // Field type definitions for query validation
3449
+ const KYC_FIELD_TYPES = {
3450
+ id: 'number',
3451
+ status: 'number',
3452
+ kind: 'number',
3453
+ subject_id: 'number',
3454
+ user_id: 'number',
3455
+ inserted_at: 'date',
3456
+ updated_at: 'date',
3457
+ };
3458
+ class KycResource {
3459
+ constructor(client) {
3460
+ this.client = client;
3461
+ }
3462
+ /**
3463
+ * List KYC records with pagination and filtering
3464
+ * Requires Client-Id header to be set in the configuration
3465
+ *
3466
+ * @example
3467
+ * await kyc.list({ status: 'pending' })
3468
+ */
3469
+ async list(params) {
3470
+ return this.client.get('/legal_requests', params);
3471
+ }
3472
+ /**
3473
+ * Query KYC records with advanced filtering
3474
+ * Supports all query system features (ranges, arrays, date ranges, etc.)
3475
+ *
3476
+ * @example
3477
+ * await kyc.query({ status: ['pending', 'in_review'], inserted_at: { after: '2024-01-01' } })
3478
+ */
3479
+ async query(params) {
3480
+ const processedQuery = processQuery(params || {}, KYC_FIELD_TYPES, { validate: true, context: 'legal_request' });
3481
+ return this.list(processedQuery);
3482
+ }
3483
+ /**
3484
+ * Create a fluent query builder for KYC requests
3485
+ *
3486
+ * @example
3487
+ * await sdk.kyc.createQueryBuilder().whereStatus('pending').execute()
3488
+ */
3489
+ createQueryBuilder(initialQuery) {
3490
+ return new KycQueryBuilder(this, initialQuery);
3491
+ }
3492
+ /**
3493
+ * List KYC records with pagination and filtering (alias for list)
3494
+ * @deprecated Use list() or query() instead
3495
+ * Requires Client-Id header to be set in the configuration
3496
+ */
3497
+ async listRequests(params) {
3498
+ return this.list(params);
3499
+ }
3500
+ /**
3501
+ * Get a specific KYC request by ID
3502
+ * Requires Client-Id header to be set in the configuration
3503
+ */
3504
+ async get(id) {
3505
+ return this.client.get(`/legal_requests/${id}`);
3506
+ }
3507
+ /**
3508
+ * Request a limit increase
3509
+ * Requires Client-Id header to be set in the configuration
3510
+ */
3511
+ async requestLimitIncrease(data) {
3512
+ return this.client.post('/legal_requests', data);
3513
+ }
3514
+ /**
3515
+ * Upload a document for KYC verification
3516
+ * Requires Client-Id header to be set in the configuration
3517
+ */
3518
+ async uploadDocument(data) {
3519
+ return this.client.post('/legal_requests', data);
3520
+ }
3521
+ /**
3522
+ * Update bank information
3523
+ * Requires Client-Id header to be set in the configuration
3524
+ */
3525
+ async updateBankInfo(data) {
3526
+ return this.client.post('/legal_requests', data);
3527
+ }
3528
+ }
3529
+
3530
+ class PaymentLinksResource {
3531
+ constructor(client) {
3532
+ this.client = client;
3533
+ }
3534
+ /**
3535
+ * Convert internal payment link data (integers) to user-facing data (strings)
3536
+ */
3537
+ translateToUserFacing(internal) {
3538
+ return {
3539
+ ...internal,
3540
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'payment_link'),
3541
+ kind: KindTranslator.toStringWithoutContext(internal.kind, 'order'),
3542
+ };
3543
+ }
3544
+ /**
3545
+ * Convert filter parameters (strings to integers where needed)
3546
+ */
3547
+ translateFilters(params) {
3548
+ if (!params)
3549
+ return params;
3550
+ const translated = { ...params };
3551
+ if (params.status && typeof params.status === 'string') {
3552
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'payment_link');
3553
+ }
3554
+ if (params.kind && typeof params.kind === 'string') {
3555
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'payment_link');
3556
+ }
3557
+ return translated;
3558
+ }
3559
+ /**
3560
+ * Convert user-facing data to internal format
3561
+ */
3562
+ translateToInternal(data) {
3563
+ const internal = { ...data };
3564
+ if ('status' in data && data.status && typeof data.status === 'string') {
3565
+ internal.status = StatusTranslator.toIntegerWithContext(data.status, 'payment_link');
3566
+ }
3567
+ if ('kind' in data && data.kind && typeof data.kind === 'string') {
3568
+ internal.kind = KindTranslator.toIntegerWithContext(data.kind, 'payment_link');
3569
+ }
3570
+ return internal;
3571
+ }
3572
+ /**
3573
+ * List payment links with filtering
3574
+ */
3575
+ async list(params) {
3576
+ var _a;
3577
+ const translatedParams = this.translateFilters(params);
3578
+ const response = await this.client.get('/payment_links', translatedParams);
3579
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
3580
+ const translatedEntries = response.result.entries.map(link => this.translateToUserFacing(link));
3581
+ return {
3582
+ state: response.state,
3583
+ result: {
3584
+ entries: translatedEntries,
3585
+ page_info: response.result.page_info
3586
+ }
3587
+ };
3588
+ }
3589
+ return {
3590
+ state: response.state,
3591
+ result: response.result
3592
+ };
3593
+ }
3594
+ /**
3595
+ * Get payment link by ID
3596
+ */
3597
+ async get(id) {
3598
+ const response = await this.client.get(`/payment_links/${id}`);
3599
+ if (response.result) {
3600
+ const translatedLink = this.translateToUserFacing(response.result);
3601
+ return {
3602
+ state: response.state,
3603
+ result: translatedLink
3604
+ };
3605
+ }
3606
+ return {
3607
+ state: response.state,
3608
+ result: response.result
3609
+ };
3610
+ }
3611
+ /**
3612
+ * Create a new payment link
3613
+ */
3614
+ async create(data) {
3615
+ const internalData = this.translateToInternal(data);
3616
+ const response = await this.client.post('/payment_links', internalData);
3617
+ if (response.result) {
3618
+ const translatedLink = this.translateToUserFacing(response.result);
3619
+ return {
3620
+ state: response.state,
3621
+ result: translatedLink
3622
+ };
3623
+ }
3624
+ return {
3625
+ state: response.state,
3626
+ result: response.result
3627
+ };
3628
+ }
3629
+ /**
3630
+ * Update a payment link
3631
+ */
3632
+ async update(id, data) {
3633
+ const internalData = this.translateToInternal(data);
3634
+ const response = await this.client.put(`/payment_links/${id}`, internalData);
3635
+ if (response.result) {
3636
+ const translatedLink = this.translateToUserFacing(response.result);
3637
+ return {
3638
+ state: response.state,
3639
+ result: translatedLink
3640
+ };
3641
+ }
3642
+ return {
3643
+ state: response.state,
3644
+ result: response.result
3645
+ };
3646
+ }
3647
+ /**
3648
+ * Delete a payment link
3649
+ */
3650
+ async delete(id) {
3651
+ return this.client.delete(`/payment_links/${id}`);
3652
+ }
3653
+ /**
3654
+ * Advanced query interface with full type safety
3655
+ * Returns a QueryBuilder that compiles to the appropriate filter format
3656
+ *
3657
+ * @example
3658
+ * const links = await sdk.paymentLinks.query({
3659
+ * total: { gte: 1000 },
3660
+ * status: [1, 2],
3661
+ * inserted_at: { gte: '2024-01-01' }
3662
+ * });
3663
+ */
3664
+ async query(params) {
3665
+ const processedQuery = processQuery(params, PAYMENT_LINK_FIELD_TYPES, { validate: true, context: 'payment_link' });
3666
+ return this.list(processedQuery);
3667
+ }
3668
+ /**
3669
+ * Create a fluent query builder for payment links
3670
+ *
3671
+ * @example
3672
+ * const links = await sdk.paymentLinks.createQueryBuilder()
3673
+ * .whereTotalGreaterThan(1000)
3674
+ * .whereStatusIn([1, 2])
3675
+ * .orderBy('inserted_at', 'desc')
3676
+ * .limit(50)
3677
+ * .execute();
3678
+ */
3679
+ createQueryBuilder() {
3680
+ return new PaymentLinkQueryBuilder(this);
3681
+ }
3682
+ }
3683
+
3684
+ class FinancialAccountsResource {
3685
+ constructor(client) {
3686
+ this.client = client;
3687
+ }
3688
+ /**
3689
+ * List financial accounts with filtering
3690
+ */
3691
+ async list(params) {
3692
+ return this.client.get('/financial_accounts', params);
131
3693
  }
132
- // Get current configuration (without sensitive data)
133
- getConfig() {
134
- const { bearerToken, ...config } = this.config;
135
- return config;
3694
+ /**
3695
+ * Get financial account by ID
3696
+ */
3697
+ async get(id) {
3698
+ return this.client.get(`/financial_accounts/${id}`);
136
3699
  }
137
- }
138
- class InkressApiError extends Error {
139
- constructor(message, status, data) {
140
- super(message);
141
- this.name = 'InkressApiError';
142
- this.status = status;
143
- this.data = data;
3700
+ /**
3701
+ * Create a new financial account
3702
+ */
3703
+ async create(data) {
3704
+ return this.client.post('/financial_accounts', data);
3705
+ }
3706
+ /**
3707
+ * Update a financial account
3708
+ */
3709
+ async update(id, data) {
3710
+ return this.client.put(`/financial_accounts/${id}`, data);
3711
+ }
3712
+ /**
3713
+ * Advanced query interface with full type safety
3714
+ *
3715
+ * @example
3716
+ * const accounts = await sdk.financialAccounts.query({
3717
+ * type: 'bank',
3718
+ * active: true,
3719
+ * provider: { contains: 'stripe' }
3720
+ * });
3721
+ */
3722
+ async query(params) {
3723
+ const processedQuery = processQuery(params, FINANCIAL_ACCOUNT_FIELD_TYPES, { validate: true });
3724
+ return this.list(processedQuery);
3725
+ }
3726
+ /**
3727
+ * Create a fluent query builder for financial accounts
3728
+ *
3729
+ * @example
3730
+ * const accounts = await sdk.financialAccounts.createQueryBuilder()
3731
+ * .whereTypeEquals('bank')
3732
+ * .whereActiveEquals(true)
3733
+ * .orderBy('inserted_at', 'desc')
3734
+ * .execute();
3735
+ */
3736
+ createQueryBuilder() {
3737
+ return new FinancialAccountQueryBuilder(this);
144
3738
  }
145
3739
  }
146
3740
 
147
- class MerchantsResource {
3741
+ class FinancialRequestsResource {
148
3742
  constructor(client) {
149
3743
  this.client = client;
150
3744
  }
151
3745
  /**
152
- * List merchants with pagination and filtering
3746
+ * Convert filter parameters (strings to integers where needed)
3747
+ */
3748
+ translateFilters(params) {
3749
+ if (!params)
3750
+ return params;
3751
+ const translated = { ...params };
3752
+ if (params.status && typeof params.status === 'string') {
3753
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'financial_request');
3754
+ }
3755
+ return translated;
3756
+ }
3757
+ /**
3758
+ * Convert user-facing data to internal format
3759
+ */
3760
+ translateToInternal(data) {
3761
+ const internal = { ...data };
3762
+ if ('status' in data && data.status && typeof data.status === 'string') {
3763
+ internal.status = StatusTranslator.toIntegerWithContext(data.status, 'financial_request');
3764
+ }
3765
+ return internal;
3766
+ }
3767
+ /**
3768
+ * List financial requests with filtering
153
3769
  */
154
3770
  async list(params) {
155
- return this.client.get('/merchants', params);
3771
+ const translatedParams = this.translateFilters(params);
3772
+ return this.client.get('/financial_requests', translatedParams);
156
3773
  }
157
3774
  /**
158
- * Get a specific merchant by ID
3775
+ * Get financial request by ID
159
3776
  */
160
3777
  async get(id) {
161
- return this.client.get(`/merchants/${id}`);
3778
+ return this.client.get(`/financial_requests/${id}`);
162
3779
  }
163
3780
  /**
164
- * Create a new merchant
3781
+ * Create a new financial request
165
3782
  */
166
3783
  async create(data) {
167
- return this.client.post('/merchants', data);
3784
+ const internalData = this.translateToInternal(data);
3785
+ return this.client.post('/financial_requests', internalData);
168
3786
  }
169
3787
  /**
170
- * Update an existing merchant
3788
+ * Advanced query interface with full type safety
3789
+ *
3790
+ * @example
3791
+ * const requests = await sdk.financialRequests.query({
3792
+ * status: [1, 2],
3793
+ * total: { gte: 5000 },
3794
+ * merchant_id: 123
3795
+ * });
171
3796
  */
172
- async update(id, data) {
173
- return this.client.put(`/merchants/${id}`, data);
3797
+ async query(params) {
3798
+ const processedQuery = processQuery(params, FINANCIAL_REQUEST_FIELD_TYPES, { validate: true, context: 'financial_request' });
3799
+ return this.list(processedQuery);
3800
+ }
3801
+ /**
3802
+ * Create a fluent query builder for financial requests
3803
+ *
3804
+ * @example
3805
+ * const requests = await sdk.financialRequests.createQueryBuilder()
3806
+ * .whereStatusIn([1, 2])
3807
+ * .whereTotalGreaterThan(5000)
3808
+ * .orderBy('inserted_at', 'desc')
3809
+ * .execute();
3810
+ */
3811
+ createQueryBuilder() {
3812
+ return new FinancialRequestQueryBuilder(this);
174
3813
  }
175
3814
  }
176
3815
 
177
- class CategoriesResource {
3816
+ class WebhookUrlsResource {
178
3817
  constructor(client) {
179
3818
  this.client = client;
180
3819
  }
181
3820
  /**
182
- * List categories with pagination and filtering
183
- * Requires Client-Id header to be set in the configuration
3821
+ * List webhook URLs with filtering
184
3822
  */
185
3823
  async list(params) {
186
- return this.client.get('/categories', params);
3824
+ return this.client.get('/webhook_urls', params);
187
3825
  }
188
3826
  /**
189
- * Get a specific category by ID
190
- * Requires Client-Id header to be set in the configuration
3827
+ * Get webhook URL by ID
191
3828
  */
192
3829
  async get(id) {
193
- return this.client.get(`/categories/${id}`);
3830
+ return this.client.get(`/webhook_urls/${id}`);
194
3831
  }
195
3832
  /**
196
- * Create a new category
197
- * Requires Client-Id header to be set in the configuration
3833
+ * Create a new webhook URL
198
3834
  */
199
3835
  async create(data) {
200
- return this.client.post('/categories', data);
3836
+ return this.client.post('/webhook_urls', data);
201
3837
  }
202
3838
  /**
203
- * Update an existing category
204
- * Requires Client-Id header to be set in the configuration
205
- * Note: parent_id is immutable and cannot be changed after creation
3839
+ * Update a webhook URL
206
3840
  */
207
3841
  async update(id, data) {
208
- return this.client.put(`/categories/${id}`, data);
3842
+ return this.client.put(`/webhook_urls/${id}`, data);
209
3843
  }
210
3844
  /**
211
- * Delete a category
212
- * Requires Client-Id header to be set in the configuration
213
- * Note: Categories with assigned products or child categories cannot be deleted
3845
+ * Delete a webhook URL
214
3846
  */
215
3847
  async delete(id) {
216
- return this.client.delete(`/categories/${id}`);
3848
+ return this.client.delete(`/webhook_urls/${id}`);
3849
+ }
3850
+ /**
3851
+ * Advanced query interface with full type safety
3852
+ *
3853
+ * @example
3854
+ * const webhooks = await sdk.webhookUrls.query({
3855
+ * event: 'order.created',
3856
+ * merchant_id: 123
3857
+ * });
3858
+ */
3859
+ async query(params) {
3860
+ const processedQuery = processQuery(params, WEBHOOK_URL_FIELD_TYPES, { validate: true });
3861
+ return this.list(processedQuery);
3862
+ }
3863
+ /**
3864
+ * Create a fluent query builder for webhook URLs
3865
+ *
3866
+ * @example
3867
+ * const webhooks = await sdk.webhookUrls.createQueryBuilder()
3868
+ * .whereEventEquals('order.created')
3869
+ * .whereMerchantIdEquals(123)
3870
+ * .execute();
3871
+ */
3872
+ createQueryBuilder() {
3873
+ return new WebhookUrlQueryBuilder(this);
217
3874
  }
218
3875
  }
219
3876
 
220
- class OrdersResource {
3877
+ /**
3878
+ * Tokens Resource
3879
+ *
3880
+ * ⚠️ LIMITED ACCESS WARNING:
3881
+ * This resource is primarily for super_admin and platform_affiliate roles.
3882
+ * organisation_admin has limited access (view/list/create/delete only, no update).
3883
+ * Use with caution and be aware of permission restrictions.
3884
+ */
3885
+ class TokensResource {
221
3886
  constructor(client) {
222
3887
  this.client = client;
223
3888
  }
224
3889
  /**
225
- * Create a new order
226
- * Requires Client-Id header to be set in the configuration
3890
+ * Convert filter parameters (strings to integers where needed)
227
3891
  */
228
- async create(data) {
229
- return this.client.post('/orders', data);
3892
+ translateFilters(params) {
3893
+ if (!params)
3894
+ return params;
3895
+ const translated = { ...params };
3896
+ if (params.kind && typeof params.kind === 'string') {
3897
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'token');
3898
+ }
3899
+ return translated;
230
3900
  }
231
3901
  /**
232
- * Get order details by ID
233
- * Requires Client-Id header to be set in the configuration
3902
+ * Convert user-facing data to internal format
3903
+ */
3904
+ translateToInternal(data) {
3905
+ const internal = { ...data };
3906
+ if ('kind' in data && data.kind && typeof data.kind === 'string') {
3907
+ internal.kind = KindTranslator.toIntegerWithContext(data.kind, 'token');
3908
+ }
3909
+ return internal;
3910
+ }
3911
+ /**
3912
+ * List tokens with filtering
3913
+ */
3914
+ async list(params) {
3915
+ const translatedParams = this.translateFilters(params);
3916
+ return this.client.get('/tokens', translatedParams);
3917
+ }
3918
+ /**
3919
+ * Get token by ID
234
3920
  */
235
3921
  async get(id) {
236
- return this.client.get(`/orders/${id}`);
3922
+ return this.client.get(`/tokens/${id}`);
237
3923
  }
238
3924
  /**
239
- * Update order status
240
- * Requires Client-Id header to be set in the configuration
3925
+ * Create a new token
241
3926
  */
242
- async update(id, data) {
243
- return this.client.put(`/orders/${id}`, data);
3927
+ async create(data) {
3928
+ const internalData = this.translateToInternal(data);
3929
+ return this.client.post('/tokens', internalData);
244
3930
  }
245
3931
  /**
246
- * Get order status (public endpoint - no auth required)
3932
+ * Delete a token
247
3933
  */
248
- async getStatus(id) {
249
- return this.client.get(`/orders/status/${id}`);
3934
+ async delete(id) {
3935
+ return this.client.delete(`/tokens/${id}`);
250
3936
  }
251
3937
  /**
252
- * Get order list with pagination and filtering
253
- * Supports filtering by status, kind, customer email, and date range
254
- * Requires Client-Id header to be set in the configuration
3938
+ * Advanced query interface with full type safety
3939
+ *
3940
+ * @example
3941
+ * const tokens = await sdk.tokens.query({
3942
+ * enabled: true,
3943
+ * kind: [1, 2],
3944
+ * user_id: 123
3945
+ * });
255
3946
  */
256
- async list() {
257
- return this.client.get('/orders');
3947
+ async query(params) {
3948
+ const processedQuery = processQuery(params, TOKEN_FIELD_TYPES, { validate: true, context: 'token' });
3949
+ return this.list(processedQuery);
3950
+ }
3951
+ /**
3952
+ * Create a fluent query builder for tokens
3953
+ *
3954
+ * @example
3955
+ * const tokens = await sdk.tokens.createQueryBuilder()
3956
+ * .whereEnabledEquals(true)
3957
+ * .whereKindIn([1, 2])
3958
+ * .execute();
3959
+ */
3960
+ createQueryBuilder() {
3961
+ return new TokenQueryBuilder(this);
258
3962
  }
259
3963
  }
260
3964
 
261
- class ProductsResource {
3965
+ class AddressesResource {
262
3966
  constructor(client) {
263
3967
  this.client = client;
264
3968
  }
265
3969
  /**
266
- * List products with pagination and filtering
267
- * Requires Client-Id header to be set in the configuration
3970
+ * Convert filter parameters (strings to integers where needed)
3971
+ */
3972
+ translateFilters(params) {
3973
+ if (!params)
3974
+ return params;
3975
+ const translated = { ...params };
3976
+ if (params.kind && typeof params.kind === 'string') {
3977
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'address');
3978
+ }
3979
+ return translated;
3980
+ }
3981
+ /**
3982
+ * Convert user-facing data to internal format
3983
+ */
3984
+ translateToInternal(data) {
3985
+ const internal = { ...data };
3986
+ if ('kind' in data && data.kind && typeof data.kind === 'string') {
3987
+ internal.kind = KindTranslator.toIntegerWithContext(data.kind, 'address');
3988
+ }
3989
+ return internal;
3990
+ }
3991
+ /**
3992
+ * List addresses with filtering
268
3993
  */
269
3994
  async list(params) {
270
- return this.client.get('/products', params);
3995
+ const translatedParams = this.translateFilters(params);
3996
+ return this.client.get('/addresses', translatedParams);
271
3997
  }
272
3998
  /**
273
- * Get a specific product by ID
274
- * Requires Client-Id header to be set in the configuration
3999
+ * Get address by ID
275
4000
  */
276
4001
  async get(id) {
277
- return this.client.get(`/products/${id}`);
4002
+ return this.client.get(`/addresses/${id}`);
278
4003
  }
279
4004
  /**
280
- * Create a new product
281
- * Requires Client-Id header to be set in the configuration
4005
+ * Create a new address
282
4006
  */
283
4007
  async create(data) {
284
- return this.client.post('/products', data);
4008
+ const internalData = this.translateToInternal(data);
4009
+ return this.client.post('/addresses', internalData);
285
4010
  }
286
4011
  /**
287
- * Update an existing product
288
- * Requires Client-Id header to be set in the configuration
4012
+ * Update an address
289
4013
  */
290
4014
  async update(id, data) {
291
- return this.client.put(`/products/${id}`, data);
4015
+ const internalData = this.translateToInternal(data);
4016
+ return this.client.put(`/addresses/${id}`, internalData);
292
4017
  }
293
4018
  /**
294
- * Delete a product
295
- * Requires Client-Id header to be set in the configuration
4019
+ * Delete an address
296
4020
  */
297
4021
  async delete(id) {
298
- return this.client.delete(`/products/${id}`);
4022
+ return this.client.delete(`/addresses/${id}`);
4023
+ }
4024
+ /**
4025
+ * Advanced query interface with full type safety
4026
+ *
4027
+ * @example
4028
+ * const addresses = await sdk.addresses.query({
4029
+ * country: 'US',
4030
+ * state: 'CA',
4031
+ * kind: [1, 2]
4032
+ * });
4033
+ */
4034
+ async query(params) {
4035
+ const processedQuery = processQuery(params, ADDRESS_FIELD_TYPES, { validate: true });
4036
+ return this.list(processedQuery);
4037
+ }
4038
+ /**
4039
+ * Create a fluent query builder for addresses
4040
+ *
4041
+ * @example
4042
+ * const addresses = await sdk.addresses.createQueryBuilder()
4043
+ * .whereCountryEquals('US')
4044
+ * .whereStateEquals('CA')
4045
+ * .execute();
4046
+ */
4047
+ createQueryBuilder() {
4048
+ return new AddressQueryBuilder(this);
299
4049
  }
300
4050
  }
301
4051
 
302
- class BillingPlansResource {
4052
+ class CurrenciesResource {
303
4053
  constructor(client) {
304
4054
  this.client = client;
305
4055
  }
306
4056
  /**
307
- * List billing plans with pagination and filtering
308
- * Requires Client-Id header to be set in the configuration
4057
+ * List currencies with filtering
309
4058
  */
310
4059
  async list(params) {
311
- return this.client.get('/billing_plans', params);
4060
+ return this.client.get('/currencies', params);
312
4061
  }
313
4062
  /**
314
- * Get a specific billing plan by ID
315
- * Requires Client-Id header to be set in the configuration
4063
+ * Get currency by ID
316
4064
  */
317
4065
  async get(id) {
318
- return this.client.get(`/billing_plans/${id}`);
4066
+ return this.client.get(`/currencies/${id}`);
319
4067
  }
320
4068
  /**
321
- * Create a new billing plan
322
- * Requires Client-Id header to be set in the configuration
4069
+ * Create a new currency
323
4070
  */
324
4071
  async create(data) {
325
- return this.client.post('/billing_plans', data);
4072
+ return this.client.post('/currencies', data);
326
4073
  }
327
4074
  /**
328
- * Update an existing billing plan
329
- * Requires Client-Id header to be set in the configuration
4075
+ * Advanced query interface with full type safety
4076
+ *
4077
+ * @example
4078
+ * const currencies = await sdk.currencies.query({
4079
+ * code: ['USD', 'EUR'],
4080
+ * is_float: true
4081
+ * });
4082
+ */
4083
+ async query(params) {
4084
+ const processedQuery = processQuery(params, CURRENCY_FIELD_TYPES, { validate: true });
4085
+ return this.list(processedQuery);
4086
+ }
4087
+ /**
4088
+ * Create a fluent query builder for currencies
4089
+ *
4090
+ * @example
4091
+ * const currencies = await sdk.currencies.createQueryBuilder()
4092
+ * .whereCodeIn(['USD', 'EUR'])
4093
+ * .whereIsFloatEquals(true)
4094
+ * .execute();
4095
+ */
4096
+ createQueryBuilder() {
4097
+ return new CurrencyQueryBuilder(this);
4098
+ }
4099
+ }
4100
+
4101
+ class ExchangeRatesResource {
4102
+ constructor(client) {
4103
+ this.client = client;
4104
+ }
4105
+ /**
4106
+ * List exchange rates with filtering
4107
+ */
4108
+ async list(params) {
4109
+ return this.client.get('/exchange_rates', params);
4110
+ }
4111
+ /**
4112
+ * Get exchange rate by ID
4113
+ */
4114
+ async get(id) {
4115
+ return this.client.get(`/exchange_rates/${id}`);
4116
+ }
4117
+ /**
4118
+ * Create a new exchange rate
4119
+ */
4120
+ async create(data) {
4121
+ return this.client.post('/exchange_rates', data);
4122
+ }
4123
+ /**
4124
+ * Update an exchange rate
330
4125
  */
331
4126
  async update(id, data) {
332
- return this.client.put(`/billing_plans/${id}`, data);
4127
+ return this.client.put(`/exchange_rates/${id}`, data);
333
4128
  }
334
4129
  /**
335
- * Delete a billing plan
336
- * Requires Client-Id header to be set in the configuration
4130
+ * Delete an exchange rate
337
4131
  */
338
4132
  async delete(id) {
339
- return this.client.delete(`/billing_plans/${id}`);
4133
+ return this.client.delete(`/exchange_rates/${id}`);
4134
+ }
4135
+ /**
4136
+ * Advanced query interface with full type safety
4137
+ *
4138
+ * @example
4139
+ * const rates = await sdk.exchangeRates.query({
4140
+ * source_id: 1,
4141
+ * destination_id: 2,
4142
+ * rate: { gte: 1.0 }
4143
+ * });
4144
+ */
4145
+ async query(params) {
4146
+ const processedQuery = processQuery(params, EXCHANGE_RATE_FIELD_TYPES, { validate: true });
4147
+ return this.list(processedQuery);
4148
+ }
4149
+ /**
4150
+ * Create a fluent query builder for exchange rates
4151
+ *
4152
+ * @example
4153
+ * const rates = await sdk.exchangeRates.createQueryBuilder()
4154
+ * .whereSourceIdEquals(1)
4155
+ * .whereDestinationIdEquals(2)
4156
+ * .execute();
4157
+ */
4158
+ createQueryBuilder() {
4159
+ return new ExchangeRateQueryBuilder(this);
340
4160
  }
341
4161
  }
342
4162
 
343
- class SubscriptionsResource {
4163
+ class FeesResource {
344
4164
  constructor(client) {
345
4165
  this.client = client;
346
4166
  }
347
4167
  /**
348
- * List billing subscriptions with pagination and filtering
349
- * Requires Client-Id header to be set in the configuration
4168
+ * Convert filter parameters (strings to integers where needed)
4169
+ */
4170
+ translateFilters(params) {
4171
+ if (!params)
4172
+ return params;
4173
+ const translated = { ...params };
4174
+ if (params.kind && typeof params.kind === 'string') {
4175
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'fee');
4176
+ }
4177
+ return translated;
4178
+ }
4179
+ /**
4180
+ * Convert user-facing data to internal format
4181
+ */
4182
+ translateToInternal(data) {
4183
+ const internal = { ...data };
4184
+ if ('kind' in data && data.kind && typeof data.kind === 'string') {
4185
+ internal.kind = KindTranslator.toIntegerWithContext(data.kind, 'fee');
4186
+ }
4187
+ return internal;
4188
+ }
4189
+ /**
4190
+ * List fees with filtering
350
4191
  */
351
4192
  async list(params) {
352
- return this.client.get('/billing_subscriptions', params);
4193
+ const translatedParams = this.translateFilters(params);
4194
+ return this.client.get('/fees', translatedParams);
353
4195
  }
354
4196
  /**
355
- * Create a subscription payment link
356
- * Requires Client-Id header to be set in the configuration
4197
+ * Get fee by ID
357
4198
  */
358
- async createLink(data) {
359
- return this.client.post('/billing_subscriptions/link', data);
4199
+ async get(id) {
4200
+ return this.client.get(`/fees/${id}`);
360
4201
  }
361
4202
  /**
362
- * Charge an existing subscription
363
- * Requires Client-Id header to be set in the configuration
4203
+ * Create a new fee
364
4204
  */
365
- async charge(uid, data) {
366
- return this.client.post(`/billing_subscriptions/${uid}/charge`, data);
4205
+ async create(data) {
4206
+ const internalData = this.translateToInternal(data);
4207
+ return this.client.post('/fees', internalData);
367
4208
  }
368
4209
  /**
369
- * Get subscription billing periods
370
- * Requires Client-Id header to be set in the configuration
4210
+ * Update a fee
371
4211
  */
372
- async getPeriods(uid, params) {
373
- return this.client.get(`/billing_subscriptions/${uid}/periods`, params);
4212
+ async update(id, data) {
4213
+ const internalData = this.translateToInternal(data);
4214
+ return this.client.put(`/fees/${id}`, internalData);
374
4215
  }
375
4216
  /**
376
- * Cancel a subscription
377
- * Requires Client-Id header to be set in the configuration
4217
+ * Delete a fee
378
4218
  */
379
- async cancel(uid, code) {
380
- return this.client.post(`/billing_subscriptions/${uid}/cancel/${code}`);
4219
+ async delete(id) {
4220
+ return this.client.delete(`/fees/${id}`);
4221
+ }
4222
+ /**
4223
+ * Advanced query interface with full type safety
4224
+ *
4225
+ * @example
4226
+ * const fees = await sdk.fees.query({
4227
+ * kind: [1, 2],
4228
+ * total: { gte: 100 },
4229
+ * currency_code: 'USD'
4230
+ * });
4231
+ */
4232
+ async query(params) {
4233
+ const processedQuery = processQuery(params, FEE_FIELD_TYPES, { validate: true, context: 'fee' });
4234
+ return this.list(processedQuery);
4235
+ }
4236
+ /**
4237
+ * Create a fluent query builder for fees
4238
+ *
4239
+ * @example
4240
+ * const fees = await sdk.fees.createQueryBuilder()
4241
+ * .whereKindIn([1, 2])
4242
+ * .whereTotalGreaterThan(100)
4243
+ * .execute();
4244
+ */
4245
+ createQueryBuilder() {
4246
+ return new FeeQueryBuilder(this);
381
4247
  }
382
4248
  }
383
4249
 
384
- class UsersResource {
4250
+ class PaymentMethodsResource {
385
4251
  constructor(client) {
386
4252
  this.client = client;
387
4253
  }
388
4254
  /**
389
- * List users with pagination and filtering
390
- * Requires Client-Id header to be set in the configuration
4255
+ * List payment methods with filtering
391
4256
  */
392
4257
  async list(params) {
393
- return this.client.get('/users', params);
4258
+ return this.client.get('/payment_methods', params);
394
4259
  }
395
4260
  /**
396
- * Get a specific user by ID
397
- * Requires Client-Id header to be set in the configuration
4261
+ * Get payment method by ID
398
4262
  */
399
4263
  async get(id) {
400
- return this.client.get(`/users/${id}`);
4264
+ return this.client.get(`/payment_methods/${id}`);
401
4265
  }
402
4266
  /**
403
- * Create a new user
404
- * Requires Client-Id header to be set in the configuration
4267
+ * Create a new payment method
405
4268
  */
406
4269
  async create(data) {
407
- return this.client.post('/users', data);
4270
+ return this.client.post('/payment_methods', data);
408
4271
  }
409
4272
  /**
410
- * Update an existing user
411
- * Requires Client-Id header to be set in the configuration
4273
+ * Update a payment method
412
4274
  */
413
4275
  async update(id, data) {
414
- return this.client.put(`/users/${id}`, data);
4276
+ return this.client.put(`/payment_methods/${id}`, data);
415
4277
  }
416
4278
  /**
417
- * Delete a user
418
- * Requires Client-Id header to be set in the configuration
4279
+ * Delete a payment method
419
4280
  */
420
4281
  async delete(id) {
421
- return this.client.delete(`/users/${id}`);
4282
+ return this.client.delete(`/payment_methods/${id}`);
4283
+ }
4284
+ /**
4285
+ * Advanced query interface with full type safety
4286
+ *
4287
+ * @example
4288
+ * const methods = await sdk.paymentMethods.query({
4289
+ * active: true,
4290
+ * provider: { contains: 'stripe' }
4291
+ * });
4292
+ */
4293
+ async query(params) {
4294
+ const processedQuery = processQuery(params, PAYMENT_METHOD_FIELD_TYPES, { validate: true });
4295
+ return this.list(processedQuery);
4296
+ }
4297
+ /**
4298
+ * Create a fluent query builder for payment methods
4299
+ *
4300
+ * @example
4301
+ * const methods = await sdk.paymentMethods.createQueryBuilder()
4302
+ * .whereActiveEquals(true)
4303
+ * .execute();
4304
+ */
4305
+ createQueryBuilder() {
4306
+ return new PaymentMethodQueryBuilder(this);
422
4307
  }
423
4308
  }
424
4309
 
425
- class PublicResource {
4310
+ /**
4311
+ * Transaction Entries Resource
4312
+ *
4313
+ * ⚠️ READ-ONLY RESOURCE:
4314
+ * This resource is READ-ONLY for organisation_admin and owner roles.
4315
+ * Only view and list operations are supported.
4316
+ * Create/update/delete operations require super_admin privileges.
4317
+ */
4318
+ class TransactionEntriesResource {
426
4319
  constructor(client) {
427
4320
  this.client = client;
428
4321
  }
429
4322
  /**
430
- * Get public information about a merchant by username or cname
4323
+ * List transaction entries with filtering
431
4324
  */
432
- async getMerchant(params) {
433
- return this.client.get(`/public/m`, params);
4325
+ async list(params) {
4326
+ return this.client.get('/transaction_entries', params);
434
4327
  }
435
4328
  /**
436
- * Get merchant fees (public endpoint - no auth required)
4329
+ * Get transaction entry by ID
437
4330
  */
438
- async getMerchantFees(merchantUsername, params) {
439
- return this.client.get(`/public/m/${merchantUsername}/fees`, params);
4331
+ async get(id) {
4332
+ return this.client.get(`/transaction_entries/${id}`);
440
4333
  }
441
4334
  /**
442
- * Get merchant products (public endpoint - no auth required)
4335
+ * Advanced query interface with full type safety
4336
+ * Note: Transaction entries are read-only for organisation_admin.
4337
+ * Create/update/delete operations require super_admin privileges.
4338
+ *
4339
+ * @example
4340
+ * const entries = await sdk.transactionEntries.query({
4341
+ * amount: { gte: 100 },
4342
+ * type: [1, 2],
4343
+ * transaction_id: 123
4344
+ * });
443
4345
  */
444
- async getMerchantProducts(merchantUsername, params) {
445
- return this.client.get(`/public/m/${merchantUsername}/products`, params);
4346
+ async query(params) {
4347
+ const processedQuery = processQuery(params, TRANSACTION_ENTRY_FIELD_TYPES, { validate: true, context: 'ledger_entry' });
4348
+ return this.list(processedQuery);
4349
+ }
4350
+ /**
4351
+ * Create a fluent query builder for transaction entries
4352
+ *
4353
+ * @example
4354
+ * const entries = await sdk.transactionEntries.createQueryBuilder()
4355
+ * .whereAmountGreaterThan(100)
4356
+ * .whereTypeIn([1, 2])
4357
+ * .execute();
4358
+ */
4359
+ createQueryBuilder() {
4360
+ return new TransactionEntryQueryBuilder(this);
4361
+ }
4362
+ }
4363
+
4364
+ /**
4365
+ * Generic resource handler for any endpoint
4366
+ * Provides CRUD operations for resources not yet implemented with specific types
4367
+ */
4368
+ class GenericsResource {
4369
+ constructor(client) {
4370
+ this.client = client;
4371
+ }
4372
+ /**
4373
+ * List resources from a generic endpoint
4374
+ *
4375
+ * @example
4376
+ * const data = await sdk.generics.list('/subscription_periods', { status: 1 });
4377
+ */
4378
+ async list(endpoint, params) {
4379
+ return this.client.get(endpoint, params);
4380
+ }
4381
+ /**
4382
+ * Query resources from a generic endpoint with advanced filtering
4383
+ * Supports all query system features (ranges, arrays, date ranges, etc.)
4384
+ *
4385
+ * @example
4386
+ * await sdk.generics.query('/subscription_periods', {
4387
+ * status: [1, 2],
4388
+ * inserted_at: { after: '2024-01-01' }
4389
+ * })
4390
+ */
4391
+ async query(endpoint, params) {
4392
+ const processedQuery = processQuery(params || {});
4393
+ return this.list(endpoint, processedQuery);
4394
+ }
4395
+ /**
4396
+ * Get a single resource by ID from a generic endpoint
4397
+ *
4398
+ * @example
4399
+ * const data = await sdk.generics.get('/subscription_periods', 123);
4400
+ */
4401
+ async get(endpoint, id) {
4402
+ return this.client.get(`${endpoint}/${id}`);
4403
+ }
4404
+ /**
4405
+ * Create a new resource on a generic endpoint
4406
+ *
4407
+ * @example
4408
+ * const data = await sdk.generics.create('/subscription_periods', { name: 'Monthly', days: 30 });
4409
+ */
4410
+ async create(endpoint, data) {
4411
+ return this.client.post(endpoint, data);
4412
+ }
4413
+ /**
4414
+ * Update a resource on a generic endpoint
4415
+ *
4416
+ * @example
4417
+ * const data = await sdk.generics.update('/subscription_periods', 123, { name: 'Monthly Premium' });
4418
+ */
4419
+ async update(endpoint, id, data) {
4420
+ return this.client.put(`${endpoint}/${id}`, data);
4421
+ }
4422
+ /**
4423
+ * Delete a resource from a generic endpoint
4424
+ *
4425
+ * @example
4426
+ * await sdk.generics.delete('/subscription_periods', 123);
4427
+ */
4428
+ async delete(endpoint, id) {
4429
+ return this.client.delete(`${endpoint}/${id}`);
446
4430
  }
447
4431
  }
448
4432
 
@@ -454,9 +4438,9 @@ class PublicResource {
454
4438
  * import { InkressSDK } from '@inkress/admin-sdk';
455
4439
  *
456
4440
  * const inkress = new InkressSDK({
457
- * bearerToken: 'your-jwt-token',
458
- * clientId: 'm-merchant-username', // Required for merchant-specific endpoints
459
- * endpoint: 'https://api.inkress.com', // Optional, defaults to production
4441
+ * accessToken: 'your-jwt-token',
4442
+ * username: 'merchant-username', // Optional - automatically prepended with 'm-'
4443
+ * mode: 'live', // Optional - 'live' (default) or 'sandbox'
460
4444
  * apiVersion: 'v1', // Optional, defaults to v1
461
4445
  * });
462
4446
  *
@@ -501,6 +4485,19 @@ class InkressSDK {
501
4485
  this.subscriptions = new SubscriptionsResource(this.client);
502
4486
  this.users = new UsersResource(this.client);
503
4487
  this.public = new PublicResource(this.client);
4488
+ this.kyc = new KycResource(this.client);
4489
+ this.paymentLinks = new PaymentLinksResource(this.client);
4490
+ this.financialAccounts = new FinancialAccountsResource(this.client);
4491
+ this.financialRequests = new FinancialRequestsResource(this.client);
4492
+ this.webhookUrls = new WebhookUrlsResource(this.client);
4493
+ this.tokens = new TokensResource(this.client);
4494
+ this.addresses = new AddressesResource(this.client);
4495
+ this.currencies = new CurrenciesResource(this.client);
4496
+ this.exchangeRates = new ExchangeRatesResource(this.client);
4497
+ this.fees = new FeesResource(this.client);
4498
+ this.paymentMethods = new PaymentMethodsResource(this.client);
4499
+ this.transactionEntries = new TransactionEntriesResource(this.client);
4500
+ this.generics = new GenericsResource(this.client);
504
4501
  }
505
4502
  /**
506
4503
  * Update the SDK configuration
@@ -516,5 +4513,5 @@ class InkressSDK {
516
4513
  }
517
4514
  }
518
4515
 
519
- export { HttpClient, InkressApiError, InkressSDK, InkressSDK as default };
4516
+ export { ADDRESS_FIELD_TYPES, AddressQueryBuilder, BILLING_PLAN_FIELD_TYPES, BillingPlanQueryBuilder, CATEGORY_FIELD_TYPES, CURRENCY_FIELD_TYPES, CategoryQueryBuilder, CurrencyQueryBuilder, EXCHANGE_RATE_FIELD_TYPES, ExchangeRateQueryBuilder, FEE_FIELD_TYPES, FINANCIAL_ACCOUNT_FIELD_TYPES, FINANCIAL_REQUEST_FIELD_TYPES, FeeQueryBuilder, FinancialAccountQueryBuilder, FinancialRequestQueryBuilder, HttpClient, InkressApiError, InkressSDK, MERCHANT_FIELD_TYPES, MerchantQueryBuilder, ORDER_FIELD_TYPES, OrderQueryBuilder, PAYMENT_LINK_FIELD_TYPES, PAYMENT_METHOD_FIELD_TYPES, PRODUCT_FIELD_TYPES, PaymentLinkQueryBuilder, PaymentMethodQueryBuilder, ProductQueryBuilder, QueryBuilder, SUBSCRIPTION_FIELD_TYPES, SubscriptionQueryBuilder, TOKEN_FIELD_TYPES, TRANSACTION_ENTRY_FIELD_TYPES, TokenQueryBuilder, TransactionEntryQueryBuilder, USER_FIELD_TYPES, UserQueryBuilder, WEBHOOK_URL_FIELD_TYPES, WebhookUrlQueryBuilder, InkressSDK as default, processQuery };
520
4517
  //# sourceMappingURL=index.esm.js.map