@inkress/admin-sdk 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +4166 -154
  10. package/dist/index.esm.js.map +1 -1
  11. package/dist/index.js +4203 -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 -2
  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 +27 -7
  44. package/dist/resources/public.d.ts.map +1 -1
  45. package/dist/resources/subscriptions.d.ts +86 -20
  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 +1069 -197
  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,4316 @@ 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 user-facing order data (strings) to internal data (integers)
2595
+ */
2596
+ translateOrderToInternal(userFacing) {
2597
+ const internal = { ...userFacing };
2598
+ if ('status' in userFacing && userFacing.status) {
2599
+ internal.status = typeof userFacing.status === 'string'
2600
+ ? StatusTranslator.toIntegerWithContext(userFacing.status, 'order')
2601
+ : userFacing.status;
2602
+ }
2603
+ if ('kind' in userFacing && userFacing.kind) {
2604
+ internal.kind = typeof userFacing.kind === 'string'
2605
+ ? KindTranslator.toIntegerWithContext(userFacing.kind, 'order')
2606
+ : userFacing.kind;
2607
+ }
2608
+ return internal;
2609
+ }
2610
+ /**
2611
+ * Convert filter parameters (strings to integers where needed)
2612
+ */
2613
+ translateFilters(params) {
2614
+ if (!params)
2615
+ return params;
2616
+ const translated = { ...params };
2617
+ if (params.status && typeof params.status === 'string') {
2618
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'order');
2619
+ }
2620
+ if (params.kind && typeof params.kind === 'string') {
2621
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'order');
2622
+ }
2623
+ return translated;
2624
+ }
2625
+ /**
2626
+ * Convert status update data (strings to integers where needed)
2627
+ */
2628
+ translateStatusUpdate(data) {
2629
+ const internal = { ...data };
2630
+ if (data.status && typeof data.status === 'string') {
2631
+ internal.status = StatusTranslator.toIntegerWithContext(data.status, 'order');
2632
+ }
2633
+ return internal;
2634
+ }
2635
+ /**
2636
+ * Create a new order
2637
+ * Requires Client-Id header to be set in the configuration
2638
+ */
2639
+ async create(data) {
2640
+ return this.client.post('/orders', data);
2641
+ }
2642
+ /**
2643
+ * Get order details by ID
2644
+ * Requires Client-Id header to be set in the configuration
2645
+ */
2646
+ async get(id) {
2647
+ const response = await this.client.get(`/orders/${id}`);
2648
+ if (response.result) {
2649
+ const translatedOrder = this.translateOrderToUserFacing(response.result);
2650
+ return {
2651
+ state: response.state,
2652
+ result: translatedOrder
2653
+ };
2654
+ }
2655
+ return {
2656
+ state: response.state,
2657
+ result: response.result
2658
+ };
2659
+ }
2660
+ /**
2661
+ * Update order status
2662
+ * Requires Client-Id header to be set in the configuration
2663
+ */
2664
+ async update(id, data) {
2665
+ const internalData = this.translateStatusUpdate(data);
2666
+ const response = await this.client.put(`/orders/${id}`, internalData);
2667
+ if (response.result) {
2668
+ const translatedOrder = this.translateOrderToUserFacing(response.result);
2669
+ return {
2670
+ state: response.state,
2671
+ result: translatedOrder
2672
+ };
2673
+ }
2674
+ return {
2675
+ state: response.state,
2676
+ result: response.result
2677
+ };
2678
+ }
2679
+ /**
2680
+ * Delete an order
2681
+ * Requires Client-Id header to be set in the configuration
2682
+ */
2683
+ async delete(id) {
2684
+ return this.client.delete(`/orders/${id}`);
2685
+ }
2686
+ /**
2687
+ * Get order status (public endpoint - no auth required)
2688
+ */
2689
+ async getStatus(id) {
2690
+ const response = await this.client.post(`/orders/status/${id}`);
2691
+ if (response.result) {
2692
+ const translatedOrder = this.translateOrderToUserFacing(response.result);
2693
+ return {
2694
+ state: response.state,
2695
+ result: translatedOrder
2696
+ };
2697
+ }
2698
+ return {
2699
+ state: response.state,
2700
+ result: response.result
2701
+ };
2702
+ }
2703
+ /**
2704
+ * Get order list with pagination and filtering
2705
+ * Supports filtering by any database field
2706
+ * Requires Client-Id header to be set in the configuration
2707
+ */
2708
+ async list(params) {
2709
+ var _a;
2710
+ const translatedParams = this.translateFilters(params);
2711
+ const response = await this.client.get('/orders', translatedParams);
2712
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
2713
+ const translatedEntries = response.result.entries.map(order => this.translateOrderToUserFacing(order));
2714
+ return {
2715
+ state: response.state,
2716
+ result: {
2717
+ entries: translatedEntries,
2718
+ page_info: response.result.page_info
2719
+ }
2720
+ };
2721
+ }
2722
+ return {
2723
+ state: response.state,
2724
+ result: response.result
2725
+ };
2726
+ }
2727
+ /**
2728
+ * List orders with enhanced query support
2729
+ * Supports filtering by any database field using the new query system
2730
+ * Requires Client-Id header to be set in the configuration
2731
+ *
2732
+ * @example
2733
+ * // Simple queries
2734
+ * await orders.query({ status: 'confirmed', kind: 'online' })
2735
+ *
2736
+ * // Array queries (IN operations)
2737
+ * await orders.query({ id: [1, 2, 3], status: ['confirmed', 'shipped'] })
2738
+ *
2739
+ * // Range queries
2740
+ * await orders.query({ total: { min: 100, max: 1000 } })
2741
+ *
2742
+ * // String searches
2743
+ * await orders.query({ reference_id: { contains: 'ORDER-2024' } })
2744
+ *
2745
+ * // Date range queries
2746
+ * await orders.query({ inserted_at: { after: '2024-01-01', before: '2024-12-31' } })
2747
+ *
2748
+ * // Combined queries
2749
+ * await orders.query({
2750
+ * status: 'confirmed',
2751
+ * total: { min: 50 },
2752
+ * inserted_at: { after: '2024-01-01' },
2753
+ * page: 1,
2754
+ * page_size: 20
2755
+ * })
2756
+ */
2757
+ async query(params) {
2758
+ var _a;
2759
+ // Process the query through the transformation system with validation and translation
2760
+ const processedQuery = processQuery(params || {}, ORDER_FIELD_TYPES, { validate: true, context: 'order' });
2761
+ const response = await this.client.get('/orders', processedQuery);
2762
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
2763
+ const translatedEntries = response.result.entries.map(order => this.translateOrderToUserFacing(order));
2764
+ return {
2765
+ state: response.state,
2766
+ result: {
2767
+ entries: translatedEntries,
2768
+ page_info: response.result.page_info
2769
+ }
2770
+ };
2771
+ }
2772
+ return {
2773
+ state: response.state,
2774
+ result: response.result
2775
+ };
2776
+ }
2777
+ /**
2778
+ * Create a query builder for orders
2779
+ * Provides a fluent interface for building complex queries
2780
+ *
2781
+ * @example
2782
+ * const orders = await sdk.orders.createQueryBuilder()
2783
+ * .whereStatus('confirmed')
2784
+ * .whereTotalRange(100, 1000)
2785
+ * .whereReferenceContains('ORDER-2024')
2786
+ * .paginate(1, 20)
2787
+ * .orderBy('inserted_at', 'desc')
2788
+ * .execute();
2789
+ */
2790
+ createQueryBuilder(initialQuery) {
2791
+ return new OrderQueryBuilder(this, initialQuery);
2792
+ }
2793
+ }
2794
+
2795
+ class ProductsResource {
2796
+ constructor(client) {
2797
+ this.client = client;
2798
+ }
2799
+ /**
2800
+ * Convert internal product data (integers) to user-facing data (strings)
2801
+ */
2802
+ translateProductToUserFacing(internal) {
2803
+ return {
2804
+ ...internal,
2805
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'product'),
2806
+ };
2807
+ }
2808
+ /**
2809
+ * Convert user-facing product data (strings) to internal data (integers)
2810
+ */
2811
+ translateProductToInternal(userFacing) {
2812
+ const internal = { ...userFacing };
2813
+ if ('status' in userFacing && userFacing.status) {
2814
+ internal.status = typeof userFacing.status === 'string'
2815
+ ? StatusTranslator.toIntegerWithContext(userFacing.status, 'product')
2816
+ : userFacing.status;
2817
+ }
2818
+ return internal;
2819
+ }
2820
+ /**
2821
+ * Convert filter parameters (strings to integers where needed)
2822
+ */
2823
+ translateFilters(params) {
2824
+ if (!params)
2825
+ return params;
2826
+ const translated = { ...params };
2827
+ if (params.status && typeof params.status === 'string') {
2828
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'product');
2829
+ }
2830
+ return translated;
2831
+ }
2832
+ /**
2833
+ * List products with pagination and filtering
2834
+ * Requires Client-Id header to be set in the configuration
2835
+ */
2836
+ async list(params) {
2837
+ var _a;
2838
+ const translatedParams = this.translateFilters(params);
2839
+ const response = await this.client.get('/products', translatedParams);
2840
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
2841
+ const translatedEntries = response.result.entries.map(product => this.translateProductToUserFacing(product));
2842
+ return {
2843
+ state: response.state,
2844
+ result: {
2845
+ entries: translatedEntries,
2846
+ page_info: response.result.page_info
2847
+ }
2848
+ };
2849
+ }
2850
+ return {
2851
+ state: response.state,
2852
+ result: response.result
2853
+ };
2854
+ }
2855
+ /**
2856
+ * Get a specific product by ID
2857
+ * Requires Client-Id header to be set in the configuration
2858
+ */
2859
+ async get(id) {
2860
+ const response = await this.client.get(`/products/${id}`);
2861
+ if (response.result) {
2862
+ const translatedProduct = this.translateProductToUserFacing(response.result);
2863
+ return {
2864
+ state: response.state,
2865
+ result: translatedProduct
2866
+ };
2867
+ }
2868
+ return {
2869
+ state: response.state,
2870
+ result: response.result
2871
+ };
2872
+ }
2873
+ /**
2874
+ * Create a new product
2875
+ * Requires Client-Id header to be set in the configuration
2876
+ */
2877
+ async create(data) {
2878
+ const internalData = this.translateProductToInternal(data);
2879
+ const response = await this.client.post('/products', internalData);
2880
+ if (response.result) {
2881
+ const translatedProduct = this.translateProductToUserFacing(response.result);
2882
+ return {
2883
+ state: response.state,
2884
+ result: translatedProduct
2885
+ };
2886
+ }
2887
+ return {
2888
+ state: response.state,
2889
+ result: response.result
2890
+ };
2891
+ }
2892
+ /**
2893
+ * Update an existing product
2894
+ * Requires Client-Id header to be set in the configuration
2895
+ */
2896
+ async update(id, data) {
2897
+ const internalData = this.translateProductToInternal(data);
2898
+ const response = await this.client.put(`/products/${id}`, internalData);
2899
+ if (response.result) {
2900
+ const translatedProduct = this.translateProductToUserFacing(response.result);
2901
+ return {
2902
+ state: response.state,
2903
+ result: translatedProduct
2904
+ };
2905
+ }
2906
+ return {
2907
+ state: response.state,
2908
+ result: response.result
2909
+ };
2910
+ }
2911
+ /**
2912
+ * Delete a product
2913
+ * Requires Client-Id header to be set in the configuration
2914
+ */
2915
+ async delete(id) {
2916
+ return this.client.delete(`/products/${id}`);
2917
+ }
2918
+ /**
2919
+ * List products with enhanced query support
2920
+ * Supports filtering by any database field using the new query system
2921
+ * Requires Client-Id header to be set in the configuration
2922
+ *
2923
+ * @example
2924
+ * // Simple queries
2925
+ * await products.query({ status: 'published', public: true })
2926
+ *
2927
+ * // Array queries (IN operations)
2928
+ * await products.query({ category_id: [1, 2, 3], status: ['published', 'draft'] })
2929
+ *
2930
+ * // Range queries
2931
+ * await products.query({ price: { min: 10, max: 100 } })
2932
+ *
2933
+ * // String searches
2934
+ * await products.query({ title: { contains: 'shirt' } })
2935
+ *
2936
+ * // Combined queries
2937
+ * await products.query({
2938
+ * status: 'published',
2939
+ * price: { min: 20 },
2940
+ * public: true,
2941
+ * page: 1,
2942
+ * page_size: 20
2943
+ * })
2944
+ */
2945
+ async query(params) {
2946
+ var _a;
2947
+ // Process the query through the transformation system with validation and translation
2948
+ const processedQuery = processQuery(params || {}, PRODUCT_FIELD_TYPES, { validate: true, context: 'product' });
2949
+ const response = await this.client.get('/products', processedQuery);
2950
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
2951
+ const translatedEntries = response.result.entries.map(product => this.translateProductToUserFacing(product));
2952
+ return {
2953
+ state: response.state,
2954
+ result: {
2955
+ entries: translatedEntries,
2956
+ page_info: response.result.page_info
2957
+ }
2958
+ };
2959
+ }
2960
+ return {
2961
+ state: response.state,
2962
+ result: response.result
2963
+ };
2964
+ }
2965
+ /**
2966
+ * Create a query builder for products
2967
+ * Provides a fluent interface for building complex queries
2968
+ *
2969
+ * @example
2970
+ * const products = await sdk.products.createQueryBuilder()
2971
+ * .whereStatus('published')
2972
+ * .wherePriceRange(10, 100)
2973
+ * .whereTitleContains('shirt')
2974
+ * .wherePublic(true)
2975
+ * .paginate(1, 20)
2976
+ * .execute();
2977
+ */
2978
+ createQueryBuilder(initialQuery) {
2979
+ return new ProductQueryBuilder(this, initialQuery);
2980
+ }
2981
+ }
2982
+
2983
+ class BillingPlansResource {
2984
+ constructor(client) {
2985
+ this.client = client;
2986
+ }
2987
+ /**
2988
+ * Convert internal billing plan data (integers) to user-facing data (strings)
2989
+ */
2990
+ translateToUserFacing(internal) {
2991
+ return {
2992
+ ...internal,
2993
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'billing_plan'),
2994
+ kind: KindTranslator.toStringWithoutContext(internal.kind, 'billing_plan'),
2995
+ };
2996
+ }
2997
+ /**
2998
+ * Convert filter parameters (strings to integers where needed)
2999
+ */
3000
+ translateFilters(params) {
3001
+ if (!params)
3002
+ return params;
3003
+ const translated = { ...params };
3004
+ if (params.status && typeof params.status === 'string') {
3005
+ translated.status = StatusTranslator.toInteger(params.status);
3006
+ }
3007
+ if (params.kind && typeof params.kind === 'string') {
3008
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'billing_plan');
3009
+ }
3010
+ return translated;
3011
+ }
3012
+ /**
3013
+ * Translate billing plan data for API (contextual strings to integers)
3014
+ */
3015
+ translateToInternal(data) {
3016
+ const internal = { ...data };
3017
+ // Translate kind if present and is a string
3018
+ if ('kind' in data && data.kind && typeof data.kind === 'string') {
3019
+ internal.kind = KindTranslator.toIntegerWithContext(data.kind, 'billing_plan');
3020
+ }
3021
+ // Translate status if present and is a string (for updates)
3022
+ if ('status' in data && data.status && typeof data.status === 'string') {
3023
+ internal.status = StatusTranslator.toInteger(data.status);
3024
+ }
3025
+ return internal;
3026
+ }
3027
+ /**
3028
+ * List billing plans with pagination and filtering
3029
+ * Requires Client-Id header to be set in the configuration
3030
+ */
3031
+ async list(params) {
3032
+ var _a;
3033
+ const translatedParams = this.translateFilters(params);
3034
+ const response = await this.client.get('/billing_plans', translatedParams);
3035
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
3036
+ const translatedEntries = response.result.entries.map(plan => this.translateToUserFacing(plan));
3037
+ return {
3038
+ state: response.state,
3039
+ result: {
3040
+ entries: translatedEntries,
3041
+ page_info: response.result.page_info
3042
+ }
3043
+ };
3044
+ }
3045
+ return {
3046
+ state: response.state,
3047
+ result: response.result
3048
+ };
3049
+ }
3050
+ /**
3051
+ * Get a specific billing plan by ID
3052
+ * Requires Client-Id header to be set in the configuration
3053
+ */
3054
+ async get(id) {
3055
+ const response = await this.client.get(`/billing_plans/${id}`);
3056
+ if (response.result) {
3057
+ const translatedPlan = this.translateToUserFacing(response.result);
3058
+ return {
3059
+ state: response.state,
3060
+ result: translatedPlan
3061
+ };
3062
+ }
3063
+ return {
3064
+ state: response.state,
3065
+ result: response.result
3066
+ };
3067
+ }
3068
+ /**
3069
+ * Create a new billing plan
3070
+ * Requires Client-Id header to be set in the configuration
3071
+ */
3072
+ async create(data) {
3073
+ const internalData = this.translateToInternal(data);
3074
+ const response = await this.client.post('/billing_plans', internalData);
3075
+ if (response.result) {
3076
+ const translatedPlan = this.translateToUserFacing(response.result);
3077
+ return {
3078
+ state: response.state,
3079
+ result: translatedPlan
3080
+ };
3081
+ }
3082
+ return {
3083
+ state: response.state,
3084
+ result: response.result
3085
+ };
3086
+ }
3087
+ /**
3088
+ * Update an existing billing plan
3089
+ * Requires Client-Id header to be set in the configuration
3090
+ */
3091
+ async update(id, data) {
3092
+ const internalData = this.translateToInternal(data);
3093
+ const response = await this.client.put(`/billing_plans/${id}`, internalData);
3094
+ if (response.result) {
3095
+ const translatedPlan = this.translateToUserFacing(response.result);
3096
+ return {
3097
+ state: response.state,
3098
+ result: translatedPlan
3099
+ };
3100
+ }
3101
+ return {
3102
+ state: response.state,
3103
+ result: response.result
3104
+ };
3105
+ }
3106
+ /**
3107
+ * Delete a billing plan
3108
+ * Requires Client-Id header to be set in the configuration
3109
+ */
3110
+ async delete(id) {
3111
+ return this.client.delete(`/billing_plans/${id}`);
3112
+ }
3113
+ /**
3114
+ * Query billing plans with enhanced query support
3115
+ * @example
3116
+ * await billingPlans.query({ kind: 'subscription', public: true })
3117
+ */
3118
+ async query(params) {
3119
+ var _a;
3120
+ const processedQuery = processQuery(params || {}, BILLING_PLAN_FIELD_TYPES, { validate: true, context: 'billing_plan' });
3121
+ const response = await this.client.get('/billing_plans', processedQuery);
3122
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
3123
+ const translatedEntries = response.result.entries.map(plan => this.translateToUserFacing(plan));
3124
+ return {
3125
+ state: response.state,
3126
+ result: {
3127
+ entries: translatedEntries,
3128
+ page_info: response.result.page_info
3129
+ }
3130
+ };
3131
+ }
3132
+ return {
3133
+ state: response.state,
3134
+ result: response.result
3135
+ };
3136
+ }
3137
+ /**
3138
+ * Create a query builder for billing plans
3139
+ * @example
3140
+ * await sdk.billingPlans.createQueryBuilder().whereKind('subscription').execute()
3141
+ */
3142
+ createQueryBuilder(initialQuery) {
3143
+ return new BillingPlanQueryBuilder(this, initialQuery);
3144
+ }
3145
+ }
3146
+
3147
+ class SubscriptionsResource {
3148
+ constructor(client) {
3149
+ this.client = client;
3150
+ }
3151
+ /**
3152
+ * Convert internal subscription data (integers) to user-facing data (strings)
3153
+ */
3154
+ translateToUserFacing(internal) {
3155
+ const result = {
3156
+ ...internal,
3157
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'billing_subscription'),
3158
+ kind: KindTranslator.toStringWithoutContext(internal.kind, 'billing_subscription'),
3159
+ };
3160
+ // Translate nested billing plan if present
3161
+ if (internal.billing_plan) {
3162
+ result.billing_plan = this.translateBillingPlanToUserFacing(internal.billing_plan);
3163
+ }
3164
+ return result;
3165
+ }
3166
+ /**
3167
+ * Convert internal billing plan data to user-facing billing plan
3168
+ */
3169
+ translateBillingPlanToUserFacing(internal) {
3170
+ return {
3171
+ ...internal,
3172
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'billing_plan'),
3173
+ kind: KindTranslator.toStringWithoutContext(internal.kind, 'billing_plan'),
3174
+ };
3175
+ }
3176
+ /**
3177
+ * Convert filter parameters (strings to integers where needed)
3178
+ */
3179
+ translateFilters(params) {
3180
+ if (!params)
3181
+ return params;
3182
+ const translated = { ...params };
3183
+ if (params.status && typeof params.status === 'string') {
3184
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'billing_subscription');
3185
+ }
3186
+ return translated;
3187
+ }
3188
+ /**
3189
+ * Translate subscription data for API (contextual strings to integers)
3190
+ */
3191
+ translateToInternal(data) {
3192
+ const internal = { ...data };
3193
+ // Translate status if present and is a string
3194
+ if (data.status && typeof data.status === 'string') {
3195
+ internal.status = StatusTranslator.toIntegerWithContext(data.status, 'billing_subscription');
3196
+ }
3197
+ // Translate kind if present and is a string
3198
+ if (data.kind && typeof data.kind === 'string') {
3199
+ internal.kind = KindTranslator.toInteger(data.kind);
3200
+ }
3201
+ return internal;
3202
+ }
3203
+ /**
3204
+ * List billing subscriptions with pagination and filtering
3205
+ * Requires Client-Id header to be set in the configuration
3206
+ */
3207
+ async list(params) {
3208
+ var _a;
3209
+ const translatedParams = this.translateFilters(params);
3210
+ const response = await this.client.get('/billing_subscriptions', translatedParams);
3211
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
3212
+ const translatedEntries = response.result.entries.map(sub => this.translateToUserFacing(sub));
3213
+ return {
3214
+ state: response.state,
3215
+ result: {
3216
+ entries: translatedEntries,
3217
+ page_info: response.result.page_info
3218
+ }
3219
+ };
3220
+ }
3221
+ return {
3222
+ state: response.state,
3223
+ result: response.result
3224
+ };
3225
+ }
3226
+ /**
3227
+ * Gets a billing subscription by ID
3228
+ * Requires Client-Id header to be set in the configuration
3229
+ */
3230
+ async get(id) {
3231
+ const response = await this.client.get(`/billing_subscriptions/${id}`);
3232
+ if (response.result) {
3233
+ const translatedSub = this.translateToUserFacing(response.result);
3234
+ return {
3235
+ state: response.state,
3236
+ result: translatedSub
3237
+ };
3238
+ }
3239
+ return {
3240
+ state: response.state,
3241
+ result: response.result
3242
+ };
3243
+ }
3244
+ /**
3245
+ * Create a new subscription
3246
+ * Requires Client-Id header to be set in the configuration
3247
+ */
3248
+ async create(data) {
3249
+ const internalData = this.translateToInternal(data);
3250
+ const response = await this.client.post('/billing_subscriptions', internalData);
3251
+ if (response.result) {
3252
+ const translatedSub = this.translateToUserFacing(response.result);
3253
+ return {
3254
+ state: response.state,
3255
+ result: translatedSub
3256
+ };
3257
+ }
3258
+ return {
3259
+ state: response.state,
3260
+ result: response.result
3261
+ };
3262
+ }
3263
+ /**
3264
+ * Delete a subscription
3265
+ * Requires Client-Id header to be set in the configuration
3266
+ */
3267
+ async delete(id) {
3268
+ return this.client.delete(`/billing_subscriptions/${id}`);
3269
+ }
3270
+ /**
3271
+ * Create a subscription payment link
3272
+ * Requires Client-Id header to be set in the configuration
3273
+ */
3274
+ async createLink(data) {
3275
+ return this.client.post('/billing_subscriptions/link', data);
3276
+ }
3277
+ /**
3278
+ * Charge an existing subscription
3279
+ * Requires Client-Id header to be set in the configuration
3280
+ */
3281
+ async charge(uid, data) {
3282
+ return this.client.post(`/billing_subscriptions/${uid}/charge`, data);
3283
+ }
3284
+ /**
3285
+ * Record usage for a subscription (for usage-based billing)
3286
+ * Requires Client-Id header to be set in the configuration
3287
+ */
3288
+ async usage(uid, data) {
3289
+ return this.client.post(`/billing_subscriptions/${uid}/usage`, data);
3290
+ }
3291
+ /**
3292
+ * Get subscription billing periods
3293
+ * Requires Client-Id header to be set in the configuration
3294
+ */
3295
+ async getPeriods(uid, params) {
3296
+ return this.client.get(`/billing_subscriptions/${uid}/periods`, params);
3297
+ }
3298
+ /**
3299
+ * Cancel a subscription
3300
+ * Requires Client-Id header to be set in the configuration
3301
+ */
3302
+ async cancel(uid, code) {
3303
+ return this.client.post(`/billing_subscriptions/${uid}/cancel/${code}`);
3304
+ }
3305
+ /**
3306
+ * Query subscriptions with enhanced query support
3307
+ * @example
3308
+ * await subscriptions.query({ status: 'active', billing_plan_id: 123 })
3309
+ */
3310
+ async query(params) {
3311
+ const processedQuery = processQuery(params || {}, SUBSCRIPTION_FIELD_TYPES, { validate: true, context: 'billing_subscription' });
3312
+ return this.client.get('/billing_subscriptions', processedQuery);
3313
+ }
3314
+ /**
3315
+ * Create a query builder for subscriptions
3316
+ * @example
3317
+ * await sdk.subscriptions.createQueryBuilder().whereStatus('active').execute()
3318
+ */
3319
+ createQueryBuilder(initialQuery) {
3320
+ return new SubscriptionQueryBuilder(this, initialQuery);
3321
+ }
3322
+ }
3323
+
3324
+ class UsersResource {
3325
+ constructor(client) {
3326
+ this.client = client;
3327
+ }
3328
+ /**
3329
+ * Convert internal user data (integers) to user-facing data (strings)
3330
+ */
3331
+ translateUserToUserFacing(internal) {
3332
+ return {
3333
+ ...internal,
3334
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'account'),
3335
+ kind: KindTranslator.toStringWithoutContext(internal.kind, 'user'),
3336
+ };
3337
+ }
3338
+ /**
3339
+ * Convert user-facing user data (strings) to internal data (integers)
3340
+ */
3341
+ translateUserToInternal(userFacing) {
3342
+ const internal = { ...userFacing };
3343
+ if ('status' in userFacing && userFacing.status) {
3344
+ if (typeof userFacing.status === 'string') {
3345
+ internal.status = StatusTranslator.toIntegerWithContext(userFacing.status, 'account');
3346
+ }
3347
+ else {
3348
+ internal.status = userFacing.status;
3349
+ }
3350
+ }
3351
+ if ('kind' in userFacing && userFacing.kind) {
3352
+ if (typeof userFacing.kind === 'string') {
3353
+ internal.kind = KindTranslator.toIntegerWithContext(userFacing.kind, 'user');
3354
+ }
3355
+ else {
3356
+ internal.kind = userFacing.kind;
3357
+ }
3358
+ }
3359
+ return internal;
3360
+ }
3361
+ /**
3362
+ * Convert filter parameters (strings to integers where needed)
3363
+ */
3364
+ translateFilters(params) {
3365
+ if (!params)
3366
+ return params;
3367
+ const translated = { ...params };
3368
+ if (params.status && typeof params.status === 'string') {
3369
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'account');
3370
+ }
3371
+ if (params.kind && typeof params.kind === 'string') {
3372
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'user');
3373
+ }
3374
+ return translated;
3375
+ }
3376
+ /**
3377
+ * List users with pagination and filtering
3378
+ * Requires Client-Id header to be set in the configuration
3379
+ */
3380
+ async list(params) {
3381
+ const translatedParams = this.translateFilters(params);
3382
+ return this.client.get('/users', translatedParams);
3383
+ }
3384
+ /**
3385
+ * Get a specific user by ID
3386
+ * Requires Client-Id header to be set in the configuration
3387
+ */
3388
+ async get(id) {
3389
+ return this.client.get(`/users/${id}`);
3390
+ }
3391
+ /**
3392
+ * Create a new user
3393
+ * Requires Client-Id header to be set in the configuration
3394
+ */
3395
+ async create(data) {
3396
+ const internalData = this.translateUserToInternal(data);
3397
+ return this.client.post('/users', internalData);
3398
+ }
3399
+ /**
3400
+ * Update an existing user
3401
+ * Requires Client-Id header to be set in the configuration
3402
+ */
3403
+ async update(id, data) {
3404
+ const translatedData = this.translateUserToInternal(data);
3405
+ return this.client.put(`/users/${id}`, translatedData);
3406
+ }
3407
+ /**
3408
+ * Delete a user
3409
+ * Requires Client-Id header to be set in the configuration
3410
+ */
3411
+ async delete(id) {
3412
+ return this.client.delete(`/users/${id}`);
3413
+ }
3414
+ /**
3415
+ * Query users with enhanced query support
3416
+ * @example
3417
+ * await users.query({ status: 'approved', level: { min: 5 } })
3418
+ */
3419
+ async query(params) {
3420
+ var _a;
3421
+ const processedQuery = processQuery(params || {}, USER_FIELD_TYPES, { validate: true });
3422
+ const translatedQuery = this.translateFilters(processedQuery);
3423
+ const response = await this.client.get('/users', translatedQuery);
3424
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
3425
+ const translatedEntries = response.result.entries.map(user => this.translateUserToUserFacing(user));
3426
+ return {
3427
+ state: response.state,
3428
+ result: { entries: translatedEntries, page_info: response.result.page_info }
3429
+ };
3430
+ }
3431
+ return { state: response.state, result: response.result };
3432
+ }
3433
+ /**
3434
+ * Create a query builder for users
3435
+ * @example
3436
+ * await sdk.users.createQueryBuilder().whereStatus('approved').execute()
3437
+ */
3438
+ createQueryBuilder(initialQuery) {
3439
+ return new UserQueryBuilder(this, initialQuery);
3440
+ }
3441
+ }
3442
+
3443
+ class PublicResource {
3444
+ constructor(client) {
3445
+ this.client = client;
3446
+ }
3447
+ /**
3448
+ * Get public information about a merchant by username or cname
3449
+ */
3450
+ async getMerchant(params) {
3451
+ return this.client.get(`/public/m`, params);
3452
+ }
3453
+ /**
3454
+ * Get merchant fees (public endpoint - no auth required)
3455
+ */
3456
+ async getMerchantFees(merchantUsername, params) {
3457
+ return this.client.get(`/public/m/${merchantUsername}/fees`, params);
3458
+ }
3459
+ /**
3460
+ * Get merchant products (public endpoint - no auth required)
3461
+ */
3462
+ async getMerchantProducts(merchantUsername, params) {
3463
+ return this.client.get(`/public/m/${merchantUsername}/products`, params);
3464
+ }
3465
+ }
3466
+
3467
+ // Field type definitions for query validation
3468
+ const KYC_FIELD_TYPES = {
3469
+ id: 'number',
3470
+ status: 'number',
3471
+ kind: 'number',
3472
+ subject_id: 'number',
3473
+ user_id: 'number',
3474
+ inserted_at: 'date',
3475
+ updated_at: 'date',
3476
+ };
3477
+ class KycResource {
3478
+ constructor(client) {
3479
+ this.client = client;
3480
+ }
3481
+ /**
3482
+ * List KYC records with pagination and filtering
3483
+ * Requires Client-Id header to be set in the configuration
3484
+ *
3485
+ * @example
3486
+ * await kyc.list({ status: 'pending' })
3487
+ */
3488
+ async list(params) {
3489
+ return this.client.get('/legal_requests', params);
3490
+ }
3491
+ /**
3492
+ * Query KYC records with advanced filtering
3493
+ * Supports all query system features (ranges, arrays, date ranges, etc.)
3494
+ *
3495
+ * @example
3496
+ * await kyc.query({ status: ['pending', 'in_review'], inserted_at: { after: '2024-01-01' } })
3497
+ */
3498
+ async query(params) {
3499
+ const processedQuery = processQuery(params || {}, KYC_FIELD_TYPES, { validate: true, context: 'legal_request' });
3500
+ return this.list(processedQuery);
3501
+ }
3502
+ /**
3503
+ * Create a fluent query builder for KYC requests
3504
+ *
3505
+ * @example
3506
+ * await sdk.kyc.createQueryBuilder().whereStatus('pending').execute()
3507
+ */
3508
+ createQueryBuilder(initialQuery) {
3509
+ return new KycQueryBuilder(this, initialQuery);
3510
+ }
3511
+ /**
3512
+ * List KYC records with pagination and filtering (alias for list)
3513
+ * @deprecated Use list() or query() instead
3514
+ * Requires Client-Id header to be set in the configuration
3515
+ */
3516
+ async listRequests(params) {
3517
+ return this.list(params);
3518
+ }
3519
+ /**
3520
+ * Get a specific KYC request by ID
3521
+ * Requires Client-Id header to be set in the configuration
3522
+ */
3523
+ async get(id) {
3524
+ return this.client.get(`/legal_requests/${id}`);
3525
+ }
3526
+ /**
3527
+ * Request a limit increase
3528
+ * Requires Client-Id header to be set in the configuration
3529
+ */
3530
+ async requestLimitIncrease(data) {
3531
+ return this.client.post('/legal_requests', data);
3532
+ }
3533
+ /**
3534
+ * Upload a document for KYC verification
3535
+ * Requires Client-Id header to be set in the configuration
3536
+ */
3537
+ async uploadDocument(data) {
3538
+ return this.client.post('/legal_requests', data);
3539
+ }
3540
+ /**
3541
+ * Update bank information
3542
+ * Requires Client-Id header to be set in the configuration
3543
+ */
3544
+ async updateBankInfo(data) {
3545
+ return this.client.post('/legal_requests', data);
3546
+ }
3547
+ }
3548
+
3549
+ class PaymentLinksResource {
3550
+ constructor(client) {
3551
+ this.client = client;
3552
+ }
3553
+ /**
3554
+ * Convert internal payment link data (integers) to user-facing data (strings)
3555
+ */
3556
+ translateToUserFacing(internal) {
3557
+ return {
3558
+ ...internal,
3559
+ status: StatusTranslator.toStringWithoutContext(internal.status, 'payment_link'),
3560
+ kind: KindTranslator.toStringWithoutContext(internal.kind, 'order'),
3561
+ };
3562
+ }
3563
+ /**
3564
+ * Convert filter parameters (strings to integers where needed)
3565
+ */
3566
+ translateFilters(params) {
3567
+ if (!params)
3568
+ return params;
3569
+ const translated = { ...params };
3570
+ if (params.status && typeof params.status === 'string') {
3571
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'payment_link');
3572
+ }
3573
+ if (params.kind && typeof params.kind === 'string') {
3574
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'payment_link');
3575
+ }
3576
+ return translated;
3577
+ }
3578
+ /**
3579
+ * Convert user-facing data to internal format
3580
+ */
3581
+ translateToInternal(data) {
3582
+ const internal = { ...data };
3583
+ if ('status' in data && data.status && typeof data.status === 'string') {
3584
+ internal.status = StatusTranslator.toIntegerWithContext(data.status, 'payment_link');
3585
+ }
3586
+ if ('kind' in data && data.kind && typeof data.kind === 'string') {
3587
+ internal.kind = KindTranslator.toIntegerWithContext(data.kind, 'payment_link');
3588
+ }
3589
+ return internal;
3590
+ }
3591
+ /**
3592
+ * List payment links with filtering
3593
+ */
3594
+ async list(params) {
3595
+ var _a;
3596
+ const translatedParams = this.translateFilters(params);
3597
+ const response = await this.client.get('/payment_links', translatedParams);
3598
+ if ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entries) {
3599
+ const translatedEntries = response.result.entries.map(link => this.translateToUserFacing(link));
3600
+ return {
3601
+ state: response.state,
3602
+ result: {
3603
+ entries: translatedEntries,
3604
+ page_info: response.result.page_info
3605
+ }
3606
+ };
3607
+ }
3608
+ return {
3609
+ state: response.state,
3610
+ result: response.result
3611
+ };
3612
+ }
3613
+ /**
3614
+ * Get payment link by ID
3615
+ */
3616
+ async get(id) {
3617
+ const response = await this.client.get(`/payment_links/${id}`);
3618
+ if (response.result) {
3619
+ const translatedLink = this.translateToUserFacing(response.result);
3620
+ return {
3621
+ state: response.state,
3622
+ result: translatedLink
3623
+ };
3624
+ }
3625
+ return {
3626
+ state: response.state,
3627
+ result: response.result
3628
+ };
3629
+ }
3630
+ /**
3631
+ * Create a new payment link
3632
+ */
3633
+ async create(data) {
3634
+ const internalData = this.translateToInternal(data);
3635
+ const response = await this.client.post('/payment_links', internalData);
3636
+ if (response.result) {
3637
+ const translatedLink = this.translateToUserFacing(response.result);
3638
+ return {
3639
+ state: response.state,
3640
+ result: translatedLink
3641
+ };
3642
+ }
3643
+ return {
3644
+ state: response.state,
3645
+ result: response.result
3646
+ };
3647
+ }
3648
+ /**
3649
+ * Update a payment link
3650
+ */
3651
+ async update(id, data) {
3652
+ const internalData = this.translateToInternal(data);
3653
+ const response = await this.client.put(`/payment_links/${id}`, internalData);
3654
+ if (response.result) {
3655
+ const translatedLink = this.translateToUserFacing(response.result);
3656
+ return {
3657
+ state: response.state,
3658
+ result: translatedLink
3659
+ };
3660
+ }
3661
+ return {
3662
+ state: response.state,
3663
+ result: response.result
3664
+ };
3665
+ }
3666
+ /**
3667
+ * Delete a payment link
3668
+ */
3669
+ async delete(id) {
3670
+ return this.client.delete(`/payment_links/${id}`);
3671
+ }
3672
+ /**
3673
+ * Advanced query interface with full type safety
3674
+ * Returns a QueryBuilder that compiles to the appropriate filter format
3675
+ *
3676
+ * @example
3677
+ * const links = await sdk.paymentLinks.query({
3678
+ * total: { gte: 1000 },
3679
+ * status: [1, 2],
3680
+ * inserted_at: { gte: '2024-01-01' }
3681
+ * });
3682
+ */
3683
+ async query(params) {
3684
+ const processedQuery = processQuery(params, PAYMENT_LINK_FIELD_TYPES, { validate: true, context: 'payment_link' });
3685
+ return this.list(processedQuery);
3686
+ }
3687
+ /**
3688
+ * Create a fluent query builder for payment links
3689
+ *
3690
+ * @example
3691
+ * const links = await sdk.paymentLinks.createQueryBuilder()
3692
+ * .whereTotalGreaterThan(1000)
3693
+ * .whereStatusIn([1, 2])
3694
+ * .orderBy('inserted_at', 'desc')
3695
+ * .limit(50)
3696
+ * .execute();
3697
+ */
3698
+ createQueryBuilder() {
3699
+ return new PaymentLinkQueryBuilder(this);
3700
+ }
3701
+ }
3702
+
3703
+ class FinancialAccountsResource {
3704
+ constructor(client) {
3705
+ this.client = client;
3706
+ }
3707
+ /**
3708
+ * List financial accounts with filtering
3709
+ */
3710
+ async list(params) {
3711
+ return this.client.get('/financial_accounts', params);
135
3712
  }
136
- // Get current configuration (without sensitive data)
137
- getConfig() {
138
- const { bearerToken, ...config } = this.config;
139
- return config;
3713
+ /**
3714
+ * Get financial account by ID
3715
+ */
3716
+ async get(id) {
3717
+ return this.client.get(`/financial_accounts/${id}`);
140
3718
  }
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;
3719
+ /**
3720
+ * Create a new financial account
3721
+ */
3722
+ async create(data) {
3723
+ return this.client.post('/financial_accounts', data);
3724
+ }
3725
+ /**
3726
+ * Update a financial account
3727
+ */
3728
+ async update(id, data) {
3729
+ return this.client.put(`/financial_accounts/${id}`, data);
3730
+ }
3731
+ /**
3732
+ * Advanced query interface with full type safety
3733
+ *
3734
+ * @example
3735
+ * const accounts = await sdk.financialAccounts.query({
3736
+ * type: 'bank',
3737
+ * active: true,
3738
+ * provider: { contains: 'stripe' }
3739
+ * });
3740
+ */
3741
+ async query(params) {
3742
+ const processedQuery = processQuery(params, FINANCIAL_ACCOUNT_FIELD_TYPES, { validate: true });
3743
+ return this.list(processedQuery);
3744
+ }
3745
+ /**
3746
+ * Create a fluent query builder for financial accounts
3747
+ *
3748
+ * @example
3749
+ * const accounts = await sdk.financialAccounts.createQueryBuilder()
3750
+ * .whereTypeEquals('bank')
3751
+ * .whereActiveEquals(true)
3752
+ * .orderBy('inserted_at', 'desc')
3753
+ * .execute();
3754
+ */
3755
+ createQueryBuilder() {
3756
+ return new FinancialAccountQueryBuilder(this);
148
3757
  }
149
3758
  }
150
3759
 
151
- class MerchantsResource {
3760
+ class FinancialRequestsResource {
152
3761
  constructor(client) {
153
3762
  this.client = client;
154
3763
  }
155
3764
  /**
156
- * List merchants with pagination and filtering
3765
+ * Convert filter parameters (strings to integers where needed)
3766
+ */
3767
+ translateFilters(params) {
3768
+ if (!params)
3769
+ return params;
3770
+ const translated = { ...params };
3771
+ if (params.status && typeof params.status === 'string') {
3772
+ translated.status = StatusTranslator.toIntegerWithContext(params.status, 'financial_request');
3773
+ }
3774
+ return translated;
3775
+ }
3776
+ /**
3777
+ * Convert user-facing data to internal format
3778
+ */
3779
+ translateToInternal(data) {
3780
+ const internal = { ...data };
3781
+ if ('status' in data && data.status && typeof data.status === 'string') {
3782
+ internal.status = StatusTranslator.toIntegerWithContext(data.status, 'financial_request');
3783
+ }
3784
+ return internal;
3785
+ }
3786
+ /**
3787
+ * List financial requests with filtering
157
3788
  */
158
3789
  async list(params) {
159
- return this.client.get('/merchants', params);
3790
+ const translatedParams = this.translateFilters(params);
3791
+ return this.client.get('/financial_requests', translatedParams);
160
3792
  }
161
3793
  /**
162
- * Get a specific merchant by ID
3794
+ * Get financial request by ID
163
3795
  */
164
3796
  async get(id) {
165
- return this.client.get(`/merchants/${id}`);
3797
+ return this.client.get(`/financial_requests/${id}`);
166
3798
  }
167
3799
  /**
168
- * Create a new merchant
3800
+ * Create a new financial request
169
3801
  */
170
3802
  async create(data) {
171
- return this.client.post('/merchants', data);
3803
+ const internalData = this.translateToInternal(data);
3804
+ return this.client.post('/financial_requests', internalData);
172
3805
  }
173
3806
  /**
174
- * Update an existing merchant
3807
+ * Advanced query interface with full type safety
3808
+ *
3809
+ * @example
3810
+ * const requests = await sdk.financialRequests.query({
3811
+ * status: [1, 2],
3812
+ * total: { gte: 5000 },
3813
+ * merchant_id: 123
3814
+ * });
175
3815
  */
176
- async update(id, data) {
177
- return this.client.put(`/merchants/${id}`, data);
3816
+ async query(params) {
3817
+ const processedQuery = processQuery(params, FINANCIAL_REQUEST_FIELD_TYPES, { validate: true, context: 'financial_request' });
3818
+ return this.list(processedQuery);
3819
+ }
3820
+ /**
3821
+ * Create a fluent query builder for financial requests
3822
+ *
3823
+ * @example
3824
+ * const requests = await sdk.financialRequests.createQueryBuilder()
3825
+ * .whereStatusIn([1, 2])
3826
+ * .whereTotalGreaterThan(5000)
3827
+ * .orderBy('inserted_at', 'desc')
3828
+ * .execute();
3829
+ */
3830
+ createQueryBuilder() {
3831
+ return new FinancialRequestQueryBuilder(this);
178
3832
  }
179
3833
  }
180
3834
 
181
- class CategoriesResource {
3835
+ class WebhookUrlsResource {
182
3836
  constructor(client) {
183
3837
  this.client = client;
184
3838
  }
185
3839
  /**
186
- * List categories with pagination and filtering
187
- * Requires Client-Id header to be set in the configuration
3840
+ * List webhook URLs with filtering
188
3841
  */
189
3842
  async list(params) {
190
- return this.client.get('/categories', params);
3843
+ return this.client.get('/webhook_urls', params);
191
3844
  }
192
3845
  /**
193
- * Get a specific category by ID
194
- * Requires Client-Id header to be set in the configuration
3846
+ * Get webhook URL by ID
195
3847
  */
196
3848
  async get(id) {
197
- return this.client.get(`/categories/${id}`);
3849
+ return this.client.get(`/webhook_urls/${id}`);
198
3850
  }
199
3851
  /**
200
- * Create a new category
201
- * Requires Client-Id header to be set in the configuration
3852
+ * Create a new webhook URL
202
3853
  */
203
3854
  async create(data) {
204
- return this.client.post('/categories', data);
3855
+ return this.client.post('/webhook_urls', data);
205
3856
  }
206
3857
  /**
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
3858
+ * Update a webhook URL
210
3859
  */
211
3860
  async update(id, data) {
212
- return this.client.put(`/categories/${id}`, data);
3861
+ return this.client.put(`/webhook_urls/${id}`, data);
213
3862
  }
214
3863
  /**
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
3864
+ * Delete a webhook URL
218
3865
  */
219
3866
  async delete(id) {
220
- return this.client.delete(`/categories/${id}`);
3867
+ return this.client.delete(`/webhook_urls/${id}`);
3868
+ }
3869
+ /**
3870
+ * Advanced query interface with full type safety
3871
+ *
3872
+ * @example
3873
+ * const webhooks = await sdk.webhookUrls.query({
3874
+ * event: 'order.created',
3875
+ * merchant_id: 123
3876
+ * });
3877
+ */
3878
+ async query(params) {
3879
+ const processedQuery = processQuery(params, WEBHOOK_URL_FIELD_TYPES, { validate: true });
3880
+ return this.list(processedQuery);
3881
+ }
3882
+ /**
3883
+ * Create a fluent query builder for webhook URLs
3884
+ *
3885
+ * @example
3886
+ * const webhooks = await sdk.webhookUrls.createQueryBuilder()
3887
+ * .whereEventEquals('order.created')
3888
+ * .whereMerchantIdEquals(123)
3889
+ * .execute();
3890
+ */
3891
+ createQueryBuilder() {
3892
+ return new WebhookUrlQueryBuilder(this);
221
3893
  }
222
3894
  }
223
3895
 
224
- class OrdersResource {
3896
+ /**
3897
+ * Tokens Resource
3898
+ *
3899
+ * ⚠️ LIMITED ACCESS WARNING:
3900
+ * This resource is primarily for super_admin and platform_affiliate roles.
3901
+ * organisation_admin has limited access (view/list/create/delete only, no update).
3902
+ * Use with caution and be aware of permission restrictions.
3903
+ */
3904
+ class TokensResource {
225
3905
  constructor(client) {
226
3906
  this.client = client;
227
3907
  }
228
3908
  /**
229
- * Create a new order
230
- * Requires Client-Id header to be set in the configuration
3909
+ * Convert filter parameters (strings to integers where needed)
231
3910
  */
232
- async create(data) {
233
- return this.client.post('/orders', data);
3911
+ translateFilters(params) {
3912
+ if (!params)
3913
+ return params;
3914
+ const translated = { ...params };
3915
+ if (params.kind && typeof params.kind === 'string') {
3916
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'token');
3917
+ }
3918
+ return translated;
234
3919
  }
235
3920
  /**
236
- * Get order details by ID
237
- * Requires Client-Id header to be set in the configuration
3921
+ * Convert user-facing data to internal format
3922
+ */
3923
+ translateToInternal(data) {
3924
+ const internal = { ...data };
3925
+ if ('kind' in data && data.kind && typeof data.kind === 'string') {
3926
+ internal.kind = KindTranslator.toIntegerWithContext(data.kind, 'token');
3927
+ }
3928
+ return internal;
3929
+ }
3930
+ /**
3931
+ * List tokens with filtering
3932
+ */
3933
+ async list(params) {
3934
+ const translatedParams = this.translateFilters(params);
3935
+ return this.client.get('/tokens', translatedParams);
3936
+ }
3937
+ /**
3938
+ * Get token by ID
238
3939
  */
239
3940
  async get(id) {
240
- return this.client.get(`/orders/${id}`);
3941
+ return this.client.get(`/tokens/${id}`);
241
3942
  }
242
3943
  /**
243
- * Update order status
244
- * Requires Client-Id header to be set in the configuration
3944
+ * Create a new token
245
3945
  */
246
- async update(id, data) {
247
- return this.client.put(`/orders/${id}`, data);
3946
+ async create(data) {
3947
+ const internalData = this.translateToInternal(data);
3948
+ return this.client.post('/tokens', internalData);
248
3949
  }
249
3950
  /**
250
- * Get order status (public endpoint - no auth required)
3951
+ * Delete a token
251
3952
  */
252
- async getStatus(id) {
253
- return this.client.get(`/orders/status/${id}`);
3953
+ async delete(id) {
3954
+ return this.client.delete(`/tokens/${id}`);
254
3955
  }
255
3956
  /**
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
3957
+ * Advanced query interface with full type safety
3958
+ *
3959
+ * @example
3960
+ * const tokens = await sdk.tokens.query({
3961
+ * enabled: true,
3962
+ * kind: [1, 2],
3963
+ * user_id: 123
3964
+ * });
3965
+ */
3966
+ async query(params) {
3967
+ const processedQuery = processQuery(params, TOKEN_FIELD_TYPES, { validate: true, context: 'token' });
3968
+ return this.list(processedQuery);
3969
+ }
3970
+ /**
3971
+ * Create a fluent query builder for tokens
3972
+ *
3973
+ * @example
3974
+ * const tokens = await sdk.tokens.createQueryBuilder()
3975
+ * .whereEnabledEquals(true)
3976
+ * .whereKindIn([1, 2])
3977
+ * .execute();
259
3978
  */
260
- async list() {
261
- return this.client.get('/orders');
3979
+ createQueryBuilder() {
3980
+ return new TokenQueryBuilder(this);
262
3981
  }
263
3982
  }
264
3983
 
265
- class ProductsResource {
3984
+ class AddressesResource {
266
3985
  constructor(client) {
267
3986
  this.client = client;
268
3987
  }
269
3988
  /**
270
- * List products with pagination and filtering
271
- * Requires Client-Id header to be set in the configuration
3989
+ * Convert filter parameters (strings to integers where needed)
3990
+ */
3991
+ translateFilters(params) {
3992
+ if (!params)
3993
+ return params;
3994
+ const translated = { ...params };
3995
+ if (params.kind && typeof params.kind === 'string') {
3996
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'address');
3997
+ }
3998
+ return translated;
3999
+ }
4000
+ /**
4001
+ * Convert user-facing data to internal format
4002
+ */
4003
+ translateToInternal(data) {
4004
+ const internal = { ...data };
4005
+ if ('kind' in data && data.kind && typeof data.kind === 'string') {
4006
+ internal.kind = KindTranslator.toIntegerWithContext(data.kind, 'address');
4007
+ }
4008
+ return internal;
4009
+ }
4010
+ /**
4011
+ * List addresses with filtering
272
4012
  */
273
4013
  async list(params) {
274
- return this.client.get('/products', params);
4014
+ const translatedParams = this.translateFilters(params);
4015
+ return this.client.get('/addresses', translatedParams);
275
4016
  }
276
4017
  /**
277
- * Get a specific product by ID
278
- * Requires Client-Id header to be set in the configuration
4018
+ * Get address by ID
279
4019
  */
280
4020
  async get(id) {
281
- return this.client.get(`/products/${id}`);
4021
+ return this.client.get(`/addresses/${id}`);
282
4022
  }
283
4023
  /**
284
- * Create a new product
285
- * Requires Client-Id header to be set in the configuration
4024
+ * Create a new address
286
4025
  */
287
4026
  async create(data) {
288
- return this.client.post('/products', data);
4027
+ const internalData = this.translateToInternal(data);
4028
+ return this.client.post('/addresses', internalData);
289
4029
  }
290
4030
  /**
291
- * Update an existing product
292
- * Requires Client-Id header to be set in the configuration
4031
+ * Update an address
293
4032
  */
294
4033
  async update(id, data) {
295
- return this.client.put(`/products/${id}`, data);
4034
+ const internalData = this.translateToInternal(data);
4035
+ return this.client.put(`/addresses/${id}`, internalData);
296
4036
  }
297
4037
  /**
298
- * Delete a product
299
- * Requires Client-Id header to be set in the configuration
4038
+ * Delete an address
300
4039
  */
301
4040
  async delete(id) {
302
- return this.client.delete(`/products/${id}`);
4041
+ return this.client.delete(`/addresses/${id}`);
4042
+ }
4043
+ /**
4044
+ * Advanced query interface with full type safety
4045
+ *
4046
+ * @example
4047
+ * const addresses = await sdk.addresses.query({
4048
+ * country: 'US',
4049
+ * state: 'CA',
4050
+ * kind: [1, 2]
4051
+ * });
4052
+ */
4053
+ async query(params) {
4054
+ const processedQuery = processQuery(params, ADDRESS_FIELD_TYPES, { validate: true });
4055
+ return this.list(processedQuery);
4056
+ }
4057
+ /**
4058
+ * Create a fluent query builder for addresses
4059
+ *
4060
+ * @example
4061
+ * const addresses = await sdk.addresses.createQueryBuilder()
4062
+ * .whereCountryEquals('US')
4063
+ * .whereStateEquals('CA')
4064
+ * .execute();
4065
+ */
4066
+ createQueryBuilder() {
4067
+ return new AddressQueryBuilder(this);
303
4068
  }
304
4069
  }
305
4070
 
306
- class BillingPlansResource {
4071
+ class CurrenciesResource {
307
4072
  constructor(client) {
308
4073
  this.client = client;
309
4074
  }
310
4075
  /**
311
- * List billing plans with pagination and filtering
312
- * Requires Client-Id header to be set in the configuration
4076
+ * List currencies with filtering
313
4077
  */
314
4078
  async list(params) {
315
- return this.client.get('/billing_plans', params);
4079
+ return this.client.get('/currencies', params);
316
4080
  }
317
4081
  /**
318
- * Get a specific billing plan by ID
319
- * Requires Client-Id header to be set in the configuration
4082
+ * Get currency by ID
320
4083
  */
321
4084
  async get(id) {
322
- return this.client.get(`/billing_plans/${id}`);
4085
+ return this.client.get(`/currencies/${id}`);
323
4086
  }
324
4087
  /**
325
- * Create a new billing plan
326
- * Requires Client-Id header to be set in the configuration
4088
+ * Create a new currency
327
4089
  */
328
4090
  async create(data) {
329
- return this.client.post('/billing_plans', data);
4091
+ return this.client.post('/currencies', data);
330
4092
  }
331
4093
  /**
332
- * Update an existing billing plan
333
- * Requires Client-Id header to be set in the configuration
4094
+ * Advanced query interface with full type safety
4095
+ *
4096
+ * @example
4097
+ * const currencies = await sdk.currencies.query({
4098
+ * code: ['USD', 'EUR'],
4099
+ * is_float: true
4100
+ * });
4101
+ */
4102
+ async query(params) {
4103
+ const processedQuery = processQuery(params, CURRENCY_FIELD_TYPES, { validate: true });
4104
+ return this.list(processedQuery);
4105
+ }
4106
+ /**
4107
+ * Create a fluent query builder for currencies
4108
+ *
4109
+ * @example
4110
+ * const currencies = await sdk.currencies.createQueryBuilder()
4111
+ * .whereCodeIn(['USD', 'EUR'])
4112
+ * .whereIsFloatEquals(true)
4113
+ * .execute();
4114
+ */
4115
+ createQueryBuilder() {
4116
+ return new CurrencyQueryBuilder(this);
4117
+ }
4118
+ }
4119
+
4120
+ class ExchangeRatesResource {
4121
+ constructor(client) {
4122
+ this.client = client;
4123
+ }
4124
+ /**
4125
+ * List exchange rates with filtering
4126
+ */
4127
+ async list(params) {
4128
+ return this.client.get('/exchange_rates', params);
4129
+ }
4130
+ /**
4131
+ * Get exchange rate by ID
4132
+ */
4133
+ async get(id) {
4134
+ return this.client.get(`/exchange_rates/${id}`);
4135
+ }
4136
+ /**
4137
+ * Create a new exchange rate
4138
+ */
4139
+ async create(data) {
4140
+ return this.client.post('/exchange_rates', data);
4141
+ }
4142
+ /**
4143
+ * Update an exchange rate
334
4144
  */
335
4145
  async update(id, data) {
336
- return this.client.put(`/billing_plans/${id}`, data);
4146
+ return this.client.put(`/exchange_rates/${id}`, data);
337
4147
  }
338
4148
  /**
339
- * Delete a billing plan
340
- * Requires Client-Id header to be set in the configuration
4149
+ * Delete an exchange rate
341
4150
  */
342
4151
  async delete(id) {
343
- return this.client.delete(`/billing_plans/${id}`);
4152
+ return this.client.delete(`/exchange_rates/${id}`);
4153
+ }
4154
+ /**
4155
+ * Advanced query interface with full type safety
4156
+ *
4157
+ * @example
4158
+ * const rates = await sdk.exchangeRates.query({
4159
+ * source_id: 1,
4160
+ * destination_id: 2,
4161
+ * rate: { gte: 1.0 }
4162
+ * });
4163
+ */
4164
+ async query(params) {
4165
+ const processedQuery = processQuery(params, EXCHANGE_RATE_FIELD_TYPES, { validate: true });
4166
+ return this.list(processedQuery);
4167
+ }
4168
+ /**
4169
+ * Create a fluent query builder for exchange rates
4170
+ *
4171
+ * @example
4172
+ * const rates = await sdk.exchangeRates.createQueryBuilder()
4173
+ * .whereSourceIdEquals(1)
4174
+ * .whereDestinationIdEquals(2)
4175
+ * .execute();
4176
+ */
4177
+ createQueryBuilder() {
4178
+ return new ExchangeRateQueryBuilder(this);
344
4179
  }
345
4180
  }
346
4181
 
347
- class SubscriptionsResource {
4182
+ class FeesResource {
348
4183
  constructor(client) {
349
4184
  this.client = client;
350
4185
  }
351
4186
  /**
352
- * List billing subscriptions with pagination and filtering
353
- * Requires Client-Id header to be set in the configuration
4187
+ * Convert filter parameters (strings to integers where needed)
4188
+ */
4189
+ translateFilters(params) {
4190
+ if (!params)
4191
+ return params;
4192
+ const translated = { ...params };
4193
+ if (params.kind && typeof params.kind === 'string') {
4194
+ translated.kind = KindTranslator.toIntegerWithContext(params.kind, 'fee');
4195
+ }
4196
+ return translated;
4197
+ }
4198
+ /**
4199
+ * Convert user-facing data to internal format
4200
+ */
4201
+ translateToInternal(data) {
4202
+ const internal = { ...data };
4203
+ if ('kind' in data && data.kind && typeof data.kind === 'string') {
4204
+ internal.kind = KindTranslator.toIntegerWithContext(data.kind, 'fee');
4205
+ }
4206
+ return internal;
4207
+ }
4208
+ /**
4209
+ * List fees with filtering
354
4210
  */
355
4211
  async list(params) {
356
- return this.client.get('/billing_subscriptions', params);
4212
+ const translatedParams = this.translateFilters(params);
4213
+ return this.client.get('/fees', translatedParams);
357
4214
  }
358
4215
  /**
359
- * Create a subscription payment link
360
- * Requires Client-Id header to be set in the configuration
4216
+ * Get fee by ID
361
4217
  */
362
- async createLink(data) {
363
- return this.client.post('/billing_subscriptions/link', data);
4218
+ async get(id) {
4219
+ return this.client.get(`/fees/${id}`);
364
4220
  }
365
4221
  /**
366
- * Charge an existing subscription
367
- * Requires Client-Id header to be set in the configuration
4222
+ * Create a new fee
368
4223
  */
369
- async charge(uid, data) {
370
- return this.client.post(`/billing_subscriptions/${uid}/charge`, data);
4224
+ async create(data) {
4225
+ const internalData = this.translateToInternal(data);
4226
+ return this.client.post('/fees', internalData);
371
4227
  }
372
4228
  /**
373
- * Get subscription billing periods
374
- * Requires Client-Id header to be set in the configuration
4229
+ * Update a fee
375
4230
  */
376
- async getPeriods(uid, params) {
377
- return this.client.get(`/billing_subscriptions/${uid}/periods`, params);
4231
+ async update(id, data) {
4232
+ const internalData = this.translateToInternal(data);
4233
+ return this.client.put(`/fees/${id}`, internalData);
378
4234
  }
379
4235
  /**
380
- * Cancel a subscription
381
- * Requires Client-Id header to be set in the configuration
4236
+ * Delete a fee
382
4237
  */
383
- async cancel(uid, code) {
384
- return this.client.post(`/billing_subscriptions/${uid}/cancel/${code}`);
4238
+ async delete(id) {
4239
+ return this.client.delete(`/fees/${id}`);
4240
+ }
4241
+ /**
4242
+ * Advanced query interface with full type safety
4243
+ *
4244
+ * @example
4245
+ * const fees = await sdk.fees.query({
4246
+ * kind: [1, 2],
4247
+ * total: { gte: 100 },
4248
+ * currency_code: 'USD'
4249
+ * });
4250
+ */
4251
+ async query(params) {
4252
+ const processedQuery = processQuery(params, FEE_FIELD_TYPES, { validate: true, context: 'fee' });
4253
+ return this.list(processedQuery);
4254
+ }
4255
+ /**
4256
+ * Create a fluent query builder for fees
4257
+ *
4258
+ * @example
4259
+ * const fees = await sdk.fees.createQueryBuilder()
4260
+ * .whereKindIn([1, 2])
4261
+ * .whereTotalGreaterThan(100)
4262
+ * .execute();
4263
+ */
4264
+ createQueryBuilder() {
4265
+ return new FeeQueryBuilder(this);
385
4266
  }
386
4267
  }
387
4268
 
388
- class UsersResource {
4269
+ class PaymentMethodsResource {
389
4270
  constructor(client) {
390
4271
  this.client = client;
391
4272
  }
392
4273
  /**
393
- * List users with pagination and filtering
394
- * Requires Client-Id header to be set in the configuration
4274
+ * List payment methods with filtering
395
4275
  */
396
4276
  async list(params) {
397
- return this.client.get('/users', params);
4277
+ return this.client.get('/payment_methods', params);
398
4278
  }
399
4279
  /**
400
- * Get a specific user by ID
401
- * Requires Client-Id header to be set in the configuration
4280
+ * Get payment method by ID
402
4281
  */
403
4282
  async get(id) {
404
- return this.client.get(`/users/${id}`);
4283
+ return this.client.get(`/payment_methods/${id}`);
405
4284
  }
406
4285
  /**
407
- * Create a new user
408
- * Requires Client-Id header to be set in the configuration
4286
+ * Create a new payment method
409
4287
  */
410
4288
  async create(data) {
411
- return this.client.post('/users', data);
4289
+ return this.client.post('/payment_methods', data);
412
4290
  }
413
4291
  /**
414
- * Update an existing user
415
- * Requires Client-Id header to be set in the configuration
4292
+ * Update a payment method
416
4293
  */
417
4294
  async update(id, data) {
418
- return this.client.put(`/users/${id}`, data);
4295
+ return this.client.put(`/payment_methods/${id}`, data);
419
4296
  }
420
4297
  /**
421
- * Delete a user
422
- * Requires Client-Id header to be set in the configuration
4298
+ * Delete a payment method
423
4299
  */
424
4300
  async delete(id) {
425
- return this.client.delete(`/users/${id}`);
4301
+ return this.client.delete(`/payment_methods/${id}`);
4302
+ }
4303
+ /**
4304
+ * Advanced query interface with full type safety
4305
+ *
4306
+ * @example
4307
+ * const methods = await sdk.paymentMethods.query({
4308
+ * active: true,
4309
+ * provider: { contains: 'stripe' }
4310
+ * });
4311
+ */
4312
+ async query(params) {
4313
+ const processedQuery = processQuery(params, PAYMENT_METHOD_FIELD_TYPES, { validate: true });
4314
+ return this.list(processedQuery);
4315
+ }
4316
+ /**
4317
+ * Create a fluent query builder for payment methods
4318
+ *
4319
+ * @example
4320
+ * const methods = await sdk.paymentMethods.createQueryBuilder()
4321
+ * .whereActiveEquals(true)
4322
+ * .execute();
4323
+ */
4324
+ createQueryBuilder() {
4325
+ return new PaymentMethodQueryBuilder(this);
426
4326
  }
427
4327
  }
428
4328
 
429
- class PublicResource {
4329
+ /**
4330
+ * Transaction Entries Resource
4331
+ *
4332
+ * ⚠️ READ-ONLY RESOURCE:
4333
+ * This resource is READ-ONLY for organisation_admin and owner roles.
4334
+ * Only view and list operations are supported.
4335
+ * Create/update/delete operations require super_admin privileges.
4336
+ */
4337
+ class TransactionEntriesResource {
430
4338
  constructor(client) {
431
4339
  this.client = client;
432
4340
  }
433
4341
  /**
434
- * Get public information about a merchant by username or cname
4342
+ * List transaction entries with filtering
435
4343
  */
436
- async getMerchant(params) {
437
- return this.client.get(`/public/m`, params);
4344
+ async list(params) {
4345
+ return this.client.get('/transaction_entries', params);
438
4346
  }
439
4347
  /**
440
- * Get merchant fees (public endpoint - no auth required)
4348
+ * Get transaction entry by ID
441
4349
  */
442
- async getMerchantFees(merchantUsername, params) {
443
- return this.client.get(`/public/m/${merchantUsername}/fees`, params);
4350
+ async get(id) {
4351
+ return this.client.get(`/transaction_entries/${id}`);
444
4352
  }
445
4353
  /**
446
- * Get merchant products (public endpoint - no auth required)
4354
+ * Advanced query interface with full type safety
4355
+ * Note: Transaction entries are read-only for organisation_admin.
4356
+ * Create/update/delete operations require super_admin privileges.
4357
+ *
4358
+ * @example
4359
+ * const entries = await sdk.transactionEntries.query({
4360
+ * amount: { gte: 100 },
4361
+ * type: [1, 2],
4362
+ * transaction_id: 123
4363
+ * });
447
4364
  */
448
- async getMerchantProducts(merchantUsername, params) {
449
- return this.client.get(`/public/m/${merchantUsername}/products`, params);
4365
+ async query(params) {
4366
+ const processedQuery = processQuery(params, TRANSACTION_ENTRY_FIELD_TYPES, { validate: true, context: 'ledger_entry' });
4367
+ return this.list(processedQuery);
4368
+ }
4369
+ /**
4370
+ * Create a fluent query builder for transaction entries
4371
+ *
4372
+ * @example
4373
+ * const entries = await sdk.transactionEntries.createQueryBuilder()
4374
+ * .whereAmountGreaterThan(100)
4375
+ * .whereTypeIn([1, 2])
4376
+ * .execute();
4377
+ */
4378
+ createQueryBuilder() {
4379
+ return new TransactionEntryQueryBuilder(this);
4380
+ }
4381
+ }
4382
+
4383
+ /**
4384
+ * Generic resource handler for any endpoint
4385
+ * Provides CRUD operations for resources not yet implemented with specific types
4386
+ */
4387
+ class GenericsResource {
4388
+ constructor(client) {
4389
+ this.client = client;
4390
+ }
4391
+ /**
4392
+ * List resources from a generic endpoint
4393
+ *
4394
+ * @example
4395
+ * const data = await sdk.generics.list('/subscription_periods', { status: 1 });
4396
+ */
4397
+ async list(endpoint, params) {
4398
+ return this.client.get(endpoint, params);
4399
+ }
4400
+ /**
4401
+ * Query resources from a generic endpoint with advanced filtering
4402
+ * Supports all query system features (ranges, arrays, date ranges, etc.)
4403
+ *
4404
+ * @example
4405
+ * await sdk.generics.query('/subscription_periods', {
4406
+ * status: [1, 2],
4407
+ * inserted_at: { after: '2024-01-01' }
4408
+ * })
4409
+ */
4410
+ async query(endpoint, params) {
4411
+ const processedQuery = processQuery(params || {});
4412
+ return this.list(endpoint, processedQuery);
4413
+ }
4414
+ /**
4415
+ * Get a single resource by ID from a generic endpoint
4416
+ *
4417
+ * @example
4418
+ * const data = await sdk.generics.get('/subscription_periods', 123);
4419
+ */
4420
+ async get(endpoint, id) {
4421
+ return this.client.get(`${endpoint}/${id}`);
4422
+ }
4423
+ /**
4424
+ * Create a new resource on a generic endpoint
4425
+ *
4426
+ * @example
4427
+ * const data = await sdk.generics.create('/subscription_periods', { name: 'Monthly', days: 30 });
4428
+ */
4429
+ async create(endpoint, data) {
4430
+ return this.client.post(endpoint, data);
4431
+ }
4432
+ /**
4433
+ * Update a resource on a generic endpoint
4434
+ *
4435
+ * @example
4436
+ * const data = await sdk.generics.update('/subscription_periods', 123, { name: 'Monthly Premium' });
4437
+ */
4438
+ async update(endpoint, id, data) {
4439
+ return this.client.put(`${endpoint}/${id}`, data);
4440
+ }
4441
+ /**
4442
+ * Delete a resource from a generic endpoint
4443
+ *
4444
+ * @example
4445
+ * await sdk.generics.delete('/subscription_periods', 123);
4446
+ */
4447
+ async delete(endpoint, id) {
4448
+ return this.client.delete(`${endpoint}/${id}`);
450
4449
  }
451
4450
  }
452
4451
 
@@ -458,9 +4457,9 @@ class PublicResource {
458
4457
  * import { InkressSDK } from '@inkress/admin-sdk';
459
4458
  *
460
4459
  * 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
4460
+ * accessToken: 'your-jwt-token',
4461
+ * username: 'merchant-username', // Optional - automatically prepended with 'm-'
4462
+ * mode: 'live', // Optional - 'live' (default) or 'sandbox'
464
4463
  * apiVersion: 'v1', // Optional, defaults to v1
465
4464
  * });
466
4465
  *
@@ -505,6 +4504,19 @@ class InkressSDK {
505
4504
  this.subscriptions = new SubscriptionsResource(this.client);
506
4505
  this.users = new UsersResource(this.client);
507
4506
  this.public = new PublicResource(this.client);
4507
+ this.kyc = new KycResource(this.client);
4508
+ this.paymentLinks = new PaymentLinksResource(this.client);
4509
+ this.financialAccounts = new FinancialAccountsResource(this.client);
4510
+ this.financialRequests = new FinancialRequestsResource(this.client);
4511
+ this.webhookUrls = new WebhookUrlsResource(this.client);
4512
+ this.tokens = new TokensResource(this.client);
4513
+ this.addresses = new AddressesResource(this.client);
4514
+ this.currencies = new CurrenciesResource(this.client);
4515
+ this.exchangeRates = new ExchangeRatesResource(this.client);
4516
+ this.fees = new FeesResource(this.client);
4517
+ this.paymentMethods = new PaymentMethodsResource(this.client);
4518
+ this.transactionEntries = new TransactionEntriesResource(this.client);
4519
+ this.generics = new GenericsResource(this.client);
508
4520
  }
509
4521
  /**
510
4522
  * Update the SDK configuration
@@ -520,8 +4532,46 @@ class InkressSDK {
520
4532
  }
521
4533
  }
522
4534
 
4535
+ exports.ADDRESS_FIELD_TYPES = ADDRESS_FIELD_TYPES;
4536
+ exports.AddressQueryBuilder = AddressQueryBuilder;
4537
+ exports.BILLING_PLAN_FIELD_TYPES = BILLING_PLAN_FIELD_TYPES;
4538
+ exports.BillingPlanQueryBuilder = BillingPlanQueryBuilder;
4539
+ exports.CATEGORY_FIELD_TYPES = CATEGORY_FIELD_TYPES;
4540
+ exports.CURRENCY_FIELD_TYPES = CURRENCY_FIELD_TYPES;
4541
+ exports.CategoryQueryBuilder = CategoryQueryBuilder;
4542
+ exports.CurrencyQueryBuilder = CurrencyQueryBuilder;
4543
+ exports.EXCHANGE_RATE_FIELD_TYPES = EXCHANGE_RATE_FIELD_TYPES;
4544
+ exports.ExchangeRateQueryBuilder = ExchangeRateQueryBuilder;
4545
+ exports.FEE_FIELD_TYPES = FEE_FIELD_TYPES;
4546
+ exports.FINANCIAL_ACCOUNT_FIELD_TYPES = FINANCIAL_ACCOUNT_FIELD_TYPES;
4547
+ exports.FINANCIAL_REQUEST_FIELD_TYPES = FINANCIAL_REQUEST_FIELD_TYPES;
4548
+ exports.FeeQueryBuilder = FeeQueryBuilder;
4549
+ exports.FinancialAccountQueryBuilder = FinancialAccountQueryBuilder;
4550
+ exports.FinancialRequestQueryBuilder = FinancialRequestQueryBuilder;
523
4551
  exports.HttpClient = HttpClient;
524
4552
  exports.InkressApiError = InkressApiError;
525
4553
  exports.InkressSDK = InkressSDK;
4554
+ exports.MERCHANT_FIELD_TYPES = MERCHANT_FIELD_TYPES;
4555
+ exports.MerchantQueryBuilder = MerchantQueryBuilder;
4556
+ exports.ORDER_FIELD_TYPES = ORDER_FIELD_TYPES;
4557
+ exports.OrderQueryBuilder = OrderQueryBuilder;
4558
+ exports.PAYMENT_LINK_FIELD_TYPES = PAYMENT_LINK_FIELD_TYPES;
4559
+ exports.PAYMENT_METHOD_FIELD_TYPES = PAYMENT_METHOD_FIELD_TYPES;
4560
+ exports.PRODUCT_FIELD_TYPES = PRODUCT_FIELD_TYPES;
4561
+ exports.PaymentLinkQueryBuilder = PaymentLinkQueryBuilder;
4562
+ exports.PaymentMethodQueryBuilder = PaymentMethodQueryBuilder;
4563
+ exports.ProductQueryBuilder = ProductQueryBuilder;
4564
+ exports.QueryBuilder = QueryBuilder;
4565
+ exports.SUBSCRIPTION_FIELD_TYPES = SUBSCRIPTION_FIELD_TYPES;
4566
+ exports.SubscriptionQueryBuilder = SubscriptionQueryBuilder;
4567
+ exports.TOKEN_FIELD_TYPES = TOKEN_FIELD_TYPES;
4568
+ exports.TRANSACTION_ENTRY_FIELD_TYPES = TRANSACTION_ENTRY_FIELD_TYPES;
4569
+ exports.TokenQueryBuilder = TokenQueryBuilder;
4570
+ exports.TransactionEntryQueryBuilder = TransactionEntryQueryBuilder;
4571
+ exports.USER_FIELD_TYPES = USER_FIELD_TYPES;
4572
+ exports.UserQueryBuilder = UserQueryBuilder;
4573
+ exports.WEBHOOK_URL_FIELD_TYPES = WEBHOOK_URL_FIELD_TYPES;
4574
+ exports.WebhookUrlQueryBuilder = WebhookUrlQueryBuilder;
526
4575
  exports.default = InkressSDK;
4576
+ exports.processQuery = processQuery;
527
4577
  //# sourceMappingURL=index.js.map