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