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