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