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