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