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