lago-javascript-client 1.44.0 → 1.46.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/esm/mod.d.ts CHANGED
@@ -1,5 +1,15 @@
1
1
  import { Api, ApiConfig, HttpResponse } from "./openapi/client.js";
2
- export declare const Client: (apiKey: string, apiConfig?: ApiConfig) => Api<unknown>;
2
+ import type { RateLimitFetchConfig } from "./rate_limit_fetch.js";
3
+ export interface LagoClientConfig extends ApiConfig {
4
+ /**
5
+ * Rate limit retry configuration
6
+ */
7
+ rateLimitRetry?: RateLimitFetchConfig;
8
+ }
9
+ export declare const Client: (apiKey: string, apiConfig?: LagoClientConfig) => Api<unknown>;
3
10
  type ExtractLagoError<E> = E extends (...args: any) => Promise<HttpResponse<infer T, infer P>> ? P : never;
4
11
  export declare function getLagoError<T>(error: any): Promise<ExtractLagoError<T>>;
12
+ export { LagoRateLimitError } from "./rate_limit_error.js";
13
+ export { parseRateLimitHeaders, type RateLimitHeaders } from "./rate_limit_headers.js";
14
+ export { createRateLimitFetch, type RateLimitFetchConfig } from "./rate_limit_fetch.js";
5
15
  export * from "./openapi/client.js";
package/esm/mod.js CHANGED
@@ -1,13 +1,20 @@
1
1
  // deno-lint-ignore-file no-explicit-any
2
2
  import { Api } from "./openapi/client.js";
3
+ import { createRateLimitFetch } from "./rate_limit_fetch.js";
3
4
  export const Client = (apiKey, apiConfig) => {
5
+ const { rateLimitRetry, ...restConfig } = apiConfig ?? {};
6
+ // Create rate-limit-aware fetch if configured
7
+ const customFetch = rateLimitRetry
8
+ ? createRateLimitFetch((restConfig?.customFetch ?? globalThis.fetch), rateLimitRetry)
9
+ : restConfig?.customFetch;
4
10
  const api = new Api({
5
11
  securityWorker: (apiKey) => apiKey ? { headers: { Authorization: `Bearer ${apiKey}` } } : {},
6
12
  // Cloudflare Workers doesn't support some options like credentials so need to override default
7
13
  baseApiParams: {
8
14
  redirect: "follow",
9
15
  },
10
- ...apiConfig,
16
+ ...restConfig,
17
+ ...(customFetch && { customFetch }),
11
18
  });
12
19
  api.setSecurityData(apiKey);
13
20
  return api;
@@ -30,4 +37,8 @@ export async function getLagoError(error) {
30
37
  }
31
38
  throw new Error(error);
32
39
  }
40
+ // Rate limit exports
41
+ export { LagoRateLimitError } from "./rate_limit_error.js";
42
+ export { parseRateLimitHeaders } from "./rate_limit_headers.js";
43
+ export { createRateLimitFetch } from "./rate_limit_fetch.js";
33
44
  export * from "./openapi/client.js";
@@ -1045,6 +1045,17 @@ export interface AppliedCouponObject {
1045
1045
  * @example "Startup Deal"
1046
1046
  */
1047
1047
  coupon_name: string;
1048
+ /**
1049
+ * The status of the parent coupon. Can be either `active` or `terminated`.
1050
+ * @example "active"
1051
+ */
1052
+ coupon_status?: "active" | "terminated";
1053
+ /**
1054
+ * The date and time when the parent coupon was deleted. If null, the coupon still exists. It is expressed in UTC format according to the ISO 8601 datetime standard.
1055
+ * @format date-time
1056
+ * @example "2022-04-29T08:59:51Z"
1057
+ */
1058
+ coupon_deleted_at?: string | null;
1048
1059
  /**
1049
1060
  * Unique identifier of the customer, created by Lago.
1050
1061
  * @format uuid
@@ -2215,6 +2226,16 @@ export interface FeeObject {
2215
2226
  * @example "0.0"
2216
2227
  */
2217
2228
  precise_coupons_amount_cents?: string;
2229
+ /**
2230
+ * The sub total of the fee excluding taxes, in cents.
2231
+ * @example 100
2232
+ */
2233
+ sub_total_excluding_taxes_amount_cents: number;
2234
+ /**
2235
+ * The sub total of the fee excluding taxes, with precision.
2236
+ * @example "100.0"
2237
+ */
2238
+ sub_total_excluding_taxes_precise_amount_cents: string;
2218
2239
  /** List of all unit amount details for calculating the fee. */
2219
2240
  amount_details?: FeeAmountDetails;
2220
2241
  /**
@@ -3826,18 +3847,20 @@ export interface AppliedInvoiceCustomSectionObject {
3826
3847
  * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
3827
3848
  */
3828
3849
  lago_id: string;
3829
- /**
3830
- * Unique identifier of the invoice custom section that was applied.
3831
- * @format uuid
3832
- * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
3833
- */
3834
- invoice_custom_section_id: string;
3835
3850
  /**
3836
3851
  * The date of the applied invoice custom section creation, represented in ISO 8601 datetime format and expressed in Coordinated Universal Time (UTC).
3837
3852
  * @format date-time
3838
3853
  * @example "2023-07-06T14:35:58Z"
3839
3854
  */
3840
3855
  created_at: string;
3856
+ /**
3857
+ * Unique identifier of the invoice custom section that was applied.
3858
+ * @deprecated
3859
+ * @format uuid
3860
+ * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
3861
+ */
3862
+ invoice_custom_section_id?: string;
3863
+ invoice_custom_section: InvoiceCustomSectionObject;
3841
3864
  }
3842
3865
  /** Reference to a specific payment method for processing the payment. */
3843
3866
  export interface PaymentMethodReference {
@@ -7996,12 +8019,24 @@ export interface WalletTransactionObject {
7996
8019
  * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
7997
8020
  */
7998
8021
  lago_wallet_id: string;
8022
+ /**
8023
+ * Unique identifier assigned to the invoice associated with this wallet transaction. This ID is exclusively created by Lago and serves as a unique identifier for the invoice's record within the Lago system.
8024
+ * @format uuid
8025
+ * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
8026
+ */
8027
+ lago_invoice_id: string | null;
8028
+ /**
8029
+ * Unique identifier of the credit note associated with this wallet transaction. This ID is exclusively created by Lago and serves as a unique identifier for the invoice's record within the Lago system.
8030
+ * @format uuid
8031
+ * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
8032
+ */
8033
+ lago_credit_note_id: string | null;
7999
8034
  /**
8000
8035
  * Unique identifier of the invoice that was voided and triggered the creation of this inbound wallet transaction. Only present for inbound transactions on traceable wallets that were created as a result of an invoice void.
8001
8036
  * @format uuid
8002
8037
  * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
8003
8038
  */
8004
- lago_voided_invoice_id?: string | null;
8039
+ lago_voided_invoice_id: string | null;
8005
8040
  /**
8006
8041
  * The status of the wallet transaction. Possible values are `pending`, `settled` or `failed`.
8007
8042
  * @example "settled"
@@ -8038,12 +8073,12 @@ export interface WalletTransactionObject {
8038
8073
  * A boolean setting that, when set to true, delays issuing an invoice for a wallet top-up until a successful payment is made; if false, the invoice is issued immediately upon wallet top-up, regardless of the payment status. Default value of false.
8039
8074
  * @example false
8040
8075
  */
8041
- invoice_requires_successful_payment?: boolean;
8076
+ invoice_requires_successful_payment: boolean;
8042
8077
  /**
8043
8078
  * This field allows you to store a list of key-value pairs that hold additional information or custom attributes related to the data.
8044
8079
  * @example [{"key":"example key","value":"example value"},{"key":"another key","value":"another value"}]
8045
8080
  */
8046
- metadata?: {
8081
+ metadata: {
8047
8082
  /** The unique identifier for the attribute. */
8048
8083
  key?: string;
8049
8084
  /** The value associated with the key. */
@@ -8053,25 +8088,30 @@ export interface WalletTransactionObject {
8053
8088
  * The remaining unconsumed amount of an inbound wallet transaction, expressed in cents. Only present for inbound transactions on traceable wallets. Tracks how much of the original credited amount has not yet been consumed by outbound transactions.
8054
8089
  * @example 5000
8055
8090
  */
8056
- remaining_amount_cents?: number | null;
8091
+ remaining_amount_cents: number | null;
8057
8092
  /**
8058
8093
  * The remaining unconsumed amount of an inbound wallet transaction, expressed in credits. Only present for inbound transactions on traceable wallets.
8059
8094
  * @pattern ^[0-9]+.?[0-9]*$
8060
8095
  * @example "5.0"
8061
8096
  */
8062
- remaining_credit_amount?: string | null;
8097
+ remaining_credit_amount: string | null;
8098
+ /**
8099
+ * The priority of the wallet transaction, used to determine the order in which inbound transactions are consumed. Lower values are consumed first.
8100
+ * @example 50
8101
+ */
8102
+ priority: number;
8063
8103
  /**
8064
8104
  * The date when wallet transaction is settled, represented in ISO 8601 datetime format and expressed in Coordinated Universal Time (UTC).
8065
8105
  * @format date-time
8066
8106
  * @example "2022-04-29T08:59:51Z"
8067
8107
  */
8068
- settled_at?: string | null;
8108
+ settled_at: string | null;
8069
8109
  /**
8070
8110
  * The date when the wallet transaction failed, represented in ISO 8601 datetime format and expressed in Coordinated Universal Time (UTC).
8071
8111
  * @format date-time
8072
8112
  * @example "2022-04-29T08:59:51Z"
8073
8113
  */
8074
- failed_at?: string | null;
8114
+ failed_at: string | null;
8075
8115
  /**
8076
8116
  * The date of the wallet transaction creation, represented in ISO 8601 datetime format and expressed in Coordinated Universal Time (UTC).
8077
8117
  * @format date-time
@@ -8086,7 +8126,7 @@ export interface WalletTransactionObject {
8086
8126
  /** The invoice custom sections applied to invoices generated by this wallet transaction. */
8087
8127
  applied_invoice_custom_sections?: AppliedInvoiceCustomSectionObject[];
8088
8128
  /** The payment method assigned to this wallet transaction for processing the payment. */
8089
- payment_method?: PaymentMethodReference;
8129
+ payment_method: PaymentMethodReference;
8090
8130
  }
8091
8131
  export interface WalletTransactions {
8092
8132
  wallet_transactions: WalletTransactionObject[];
@@ -8753,7 +8793,7 @@ export declare class HttpClient<SecurityDataType = unknown> {
8753
8793
  }
8754
8794
  /**
8755
8795
  * @title Lago API documentation
8756
- * @version 1.44.0
8796
+ * @version 1.45.0
8757
8797
  * @license AGPLv3 (https://github.com/getlago/lago-openapi/blob/main/LICENSE)
8758
8798
  * @baseUrl https://api.getlago.com/api/v1
8759
8799
  * @externalDocs https://github.com/getlago
@@ -10288,7 +10328,9 @@ export declare class Api<SecurityDataType extends unknown> extends HttpClient<Se
10288
10328
  * @request POST:/customers/{external_customer_id}/checkout_url
10289
10329
  * @secure
10290
10330
  */
10291
- generateCustomerCheckoutUrl: (externalCustomerId: string, params?: RequestParams) => Promise<HttpResponse<CustomerCheckoutUrl, ApiErrorUnauthorized | ApiErrorUnprocessableEntity | ApiErrorNotFound>>;
10331
+ generateCustomerCheckoutUrl: (externalCustomerId: string, params?: RequestParams) => Promise<HttpResponse<{
10332
+ customer: CustomerCheckoutUrl;
10333
+ }, ApiErrorUnauthorized | ApiErrorUnprocessableEntity | ApiErrorNotFound>>;
10292
10334
  /**
10293
10335
  * @description This endpoint retrieves all payment methods of a Customer.
10294
10336
  *
@@ -148,7 +148,7 @@ export class HttpClient {
148
148
  }
149
149
  /**
150
150
  * @title Lago API documentation
151
- * @version 1.44.0
151
+ * @version 1.45.0
152
152
  * @license AGPLv3 (https://github.com/getlago/lago-openapi/blob/main/LICENSE)
153
153
  * @baseUrl https://api.getlago.com/api/v1
154
154
  * @externalDocs https://github.com/getlago
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Error class for rate limit (HTTP 429) responses
3
+ */
4
+ export declare class LagoRateLimitError extends Error {
5
+ readonly limit: number;
6
+ readonly remaining: number;
7
+ readonly reset: number;
8
+ readonly retryAfter: number;
9
+ constructor(limit: number, remaining: number, reset: number);
10
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Error class for rate limit (HTTP 429) responses
3
+ */
4
+ export class LagoRateLimitError extends Error {
5
+ limit;
6
+ remaining;
7
+ reset; // seconds until window resets
8
+ retryAfter; // milliseconds to wait before retrying
9
+ constructor(limit, remaining, reset) {
10
+ super(`Rate limit exceeded. Limit: ${limit}, Remaining: ${remaining}, Reset in: ${reset}s`);
11
+ this.name = "LagoRateLimitError";
12
+ this.limit = limit;
13
+ this.remaining = remaining;
14
+ this.reset = reset;
15
+ this.retryAfter = reset * 1000; // Convert seconds to milliseconds
16
+ // Maintain proper prototype chain for instanceof checks
17
+ Object.setPrototypeOf(this, LagoRateLimitError.prototype);
18
+ }
19
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Configuration for rate limit fetch behavior
3
+ */
4
+ export interface RateLimitFetchConfig {
5
+ /** Maximum number of retries on 429 (default: 3) */
6
+ maxRetries?: number;
7
+ /** Whether to automatically retry on rate limit (default: true) */
8
+ retryOnRateLimit?: boolean;
9
+ /** Maximum delay in milliseconds before a retry (default: 20000) */
10
+ maxRetryDelay?: number;
11
+ }
12
+ /**
13
+ * Creates a fetch wrapper that handles rate limiting with automatic retry
14
+ * Compatible with both Node.js fetch and browser fetch APIs
15
+ */
16
+ export declare function createRateLimitFetch(baseFetch: typeof fetch, config?: RateLimitFetchConfig): typeof fetch;
@@ -0,0 +1,76 @@
1
+ import { LagoRateLimitError } from "./rate_limit_error.js";
2
+ import { parseRateLimitHeaders, } from "./rate_limit_headers.js";
3
+ /**
4
+ * Creates a fetch wrapper that handles rate limiting with automatic retry
5
+ * Compatible with both Node.js fetch and browser fetch APIs
6
+ */
7
+ export function createRateLimitFetch(baseFetch, config = {}) {
8
+ const maxRetries = config.maxRetries ?? 3;
9
+ const retryOnRateLimit = config.retryOnRateLimit ?? true;
10
+ const maxRetryDelay = config.maxRetryDelay ?? 20_000;
11
+ return async function rateLimitFetch(input, init) {
12
+ let lastError;
13
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
14
+ try {
15
+ const response = await baseFetch(input, init);
16
+ // Handle 429 responses
17
+ if (response.status === 429) {
18
+ const headers = parseRateLimitHeaders(response.headers);
19
+ const limit = headers.limit ?? -1;
20
+ const remaining = headers.remaining ?? 0;
21
+ const reset = headers.reset ?? -1;
22
+ const error = new LagoRateLimitError(limit, remaining, reset);
23
+ if (!retryOnRateLimit) {
24
+ throw error;
25
+ }
26
+ if (attempt === maxRetries) {
27
+ throw error; // Max retries reached
28
+ }
29
+ // Wait before retry
30
+ const waitMs = getWaitTime(error, attempt, maxRetryDelay);
31
+ await sleep(waitMs);
32
+ continue; // Retry
33
+ }
34
+ // Success or non-rate-limit error - return the response
35
+ return response;
36
+ }
37
+ catch (error) {
38
+ lastError = error;
39
+ if (!(error instanceof LagoRateLimitError)) {
40
+ throw error; // Not a rate limit error, rethrow immediately
41
+ }
42
+ if (attempt === maxRetries) {
43
+ throw error; // Max retries reached
44
+ }
45
+ // Will retry on next iteration
46
+ }
47
+ }
48
+ throw lastError;
49
+ };
50
+ }
51
+ /**
52
+ * Calculate wait time before retry
53
+ * Uses the exact reset time from headers if available, otherwise exponential backoff
54
+ */
55
+ function getWaitTime(error, attempt, maxRetryDelay) {
56
+ let waitMs;
57
+ if (error.reset > 0) {
58
+ // Use the exact reset time from the header
59
+ waitMs = error.retryAfter;
60
+ }
61
+ else {
62
+ // Exponential backoff: 1s, 2s, 4s, 8s, etc.
63
+ waitMs = 1000 * Math.pow(2, attempt);
64
+ }
65
+ // Cap at maxRetryDelay
66
+ waitMs = Math.min(waitMs, maxRetryDelay);
67
+ // Add small jitter to prevent thundering herd (max 100ms)
68
+ const jitter = Math.random() * 100;
69
+ return waitMs + jitter;
70
+ }
71
+ /**
72
+ * Sleep for a specified number of milliseconds
73
+ */
74
+ function sleep(ms) {
75
+ return new Promise((resolve) => setTimeout(resolve, ms));
76
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Parses rate limit headers from HTTP responses
3
+ */
4
+ export interface RateLimitHeaders {
5
+ limit: number | null;
6
+ remaining: number | null;
7
+ reset: number | null;
8
+ }
9
+ /**
10
+ * Extract rate limit information from response headers
11
+ */
12
+ export declare function parseRateLimitHeaders(headers: Headers): RateLimitHeaders;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Extract rate limit information from response headers
3
+ */
4
+ export function parseRateLimitHeaders(headers) {
5
+ return {
6
+ limit: parseHeaderAsNumber(headers, "x-ratelimit-limit"),
7
+ remaining: parseHeaderAsNumber(headers, "x-ratelimit-remaining"),
8
+ reset: parseHeaderAsNumber(headers, "x-ratelimit-reset"),
9
+ };
10
+ }
11
+ /**
12
+ * Helper to parse a header value as a number
13
+ */
14
+ function parseHeaderAsNumber(headers, headerName) {
15
+ const value = headers.get(headerName);
16
+ if (value === null)
17
+ return null;
18
+ const num = parseInt(value, 10);
19
+ return isNaN(num) ? null : num;
20
+ }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "main": "./script/mod.js",
4
4
  "name": "lago-javascript-client",
5
5
  "sideEffects": false,
6
- "version": "v1.44.0",
6
+ "version": "v1.46.0",
7
7
  "description": "Lago JavaScript API Client",
8
8
  "repository": {
9
9
  "type": "git",
package/script/mod.d.ts CHANGED
@@ -1,5 +1,15 @@
1
1
  import { Api, ApiConfig, HttpResponse } from "./openapi/client.js";
2
- export declare const Client: (apiKey: string, apiConfig?: ApiConfig) => Api<unknown>;
2
+ import type { RateLimitFetchConfig } from "./rate_limit_fetch.js";
3
+ export interface LagoClientConfig extends ApiConfig {
4
+ /**
5
+ * Rate limit retry configuration
6
+ */
7
+ rateLimitRetry?: RateLimitFetchConfig;
8
+ }
9
+ export declare const Client: (apiKey: string, apiConfig?: LagoClientConfig) => Api<unknown>;
3
10
  type ExtractLagoError<E> = E extends (...args: any) => Promise<HttpResponse<infer T, infer P>> ? P : never;
4
11
  export declare function getLagoError<T>(error: any): Promise<ExtractLagoError<T>>;
12
+ export { LagoRateLimitError } from "./rate_limit_error.js";
13
+ export { parseRateLimitHeaders, type RateLimitHeaders } from "./rate_limit_headers.js";
14
+ export { createRateLimitFetch, type RateLimitFetchConfig } from "./rate_limit_fetch.js";
5
15
  export * from "./openapi/client.js";
package/script/mod.js CHANGED
@@ -14,17 +14,24 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.getLagoError = exports.Client = void 0;
17
+ exports.createRateLimitFetch = exports.parseRateLimitHeaders = exports.LagoRateLimitError = exports.getLagoError = exports.Client = void 0;
18
18
  // deno-lint-ignore-file no-explicit-any
19
19
  const client_js_1 = require("./openapi/client.js");
20
+ const rate_limit_fetch_js_1 = require("./rate_limit_fetch.js");
20
21
  const Client = (apiKey, apiConfig) => {
22
+ const { rateLimitRetry, ...restConfig } = apiConfig ?? {};
23
+ // Create rate-limit-aware fetch if configured
24
+ const customFetch = rateLimitRetry
25
+ ? (0, rate_limit_fetch_js_1.createRateLimitFetch)((restConfig?.customFetch ?? globalThis.fetch), rateLimitRetry)
26
+ : restConfig?.customFetch;
21
27
  const api = new client_js_1.Api({
22
28
  securityWorker: (apiKey) => apiKey ? { headers: { Authorization: `Bearer ${apiKey}` } } : {},
23
29
  // Cloudflare Workers doesn't support some options like credentials so need to override default
24
30
  baseApiParams: {
25
31
  redirect: "follow",
26
32
  },
27
- ...apiConfig,
33
+ ...restConfig,
34
+ ...(customFetch && { customFetch }),
28
35
  });
29
36
  api.setSecurityData(apiKey);
30
37
  return api;
@@ -49,4 +56,11 @@ async function getLagoError(error) {
49
56
  throw new Error(error);
50
57
  }
51
58
  exports.getLagoError = getLagoError;
59
+ // Rate limit exports
60
+ var rate_limit_error_js_1 = require("./rate_limit_error.js");
61
+ Object.defineProperty(exports, "LagoRateLimitError", { enumerable: true, get: function () { return rate_limit_error_js_1.LagoRateLimitError; } });
62
+ var rate_limit_headers_js_1 = require("./rate_limit_headers.js");
63
+ Object.defineProperty(exports, "parseRateLimitHeaders", { enumerable: true, get: function () { return rate_limit_headers_js_1.parseRateLimitHeaders; } });
64
+ var rate_limit_fetch_js_2 = require("./rate_limit_fetch.js");
65
+ Object.defineProperty(exports, "createRateLimitFetch", { enumerable: true, get: function () { return rate_limit_fetch_js_2.createRateLimitFetch; } });
52
66
  __exportStar(require("./openapi/client.js"), exports);
@@ -1045,6 +1045,17 @@ export interface AppliedCouponObject {
1045
1045
  * @example "Startup Deal"
1046
1046
  */
1047
1047
  coupon_name: string;
1048
+ /**
1049
+ * The status of the parent coupon. Can be either `active` or `terminated`.
1050
+ * @example "active"
1051
+ */
1052
+ coupon_status?: "active" | "terminated";
1053
+ /**
1054
+ * The date and time when the parent coupon was deleted. If null, the coupon still exists. It is expressed in UTC format according to the ISO 8601 datetime standard.
1055
+ * @format date-time
1056
+ * @example "2022-04-29T08:59:51Z"
1057
+ */
1058
+ coupon_deleted_at?: string | null;
1048
1059
  /**
1049
1060
  * Unique identifier of the customer, created by Lago.
1050
1061
  * @format uuid
@@ -2215,6 +2226,16 @@ export interface FeeObject {
2215
2226
  * @example "0.0"
2216
2227
  */
2217
2228
  precise_coupons_amount_cents?: string;
2229
+ /**
2230
+ * The sub total of the fee excluding taxes, in cents.
2231
+ * @example 100
2232
+ */
2233
+ sub_total_excluding_taxes_amount_cents: number;
2234
+ /**
2235
+ * The sub total of the fee excluding taxes, with precision.
2236
+ * @example "100.0"
2237
+ */
2238
+ sub_total_excluding_taxes_precise_amount_cents: string;
2218
2239
  /** List of all unit amount details for calculating the fee. */
2219
2240
  amount_details?: FeeAmountDetails;
2220
2241
  /**
@@ -3826,18 +3847,20 @@ export interface AppliedInvoiceCustomSectionObject {
3826
3847
  * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
3827
3848
  */
3828
3849
  lago_id: string;
3829
- /**
3830
- * Unique identifier of the invoice custom section that was applied.
3831
- * @format uuid
3832
- * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
3833
- */
3834
- invoice_custom_section_id: string;
3835
3850
  /**
3836
3851
  * The date of the applied invoice custom section creation, represented in ISO 8601 datetime format and expressed in Coordinated Universal Time (UTC).
3837
3852
  * @format date-time
3838
3853
  * @example "2023-07-06T14:35:58Z"
3839
3854
  */
3840
3855
  created_at: string;
3856
+ /**
3857
+ * Unique identifier of the invoice custom section that was applied.
3858
+ * @deprecated
3859
+ * @format uuid
3860
+ * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
3861
+ */
3862
+ invoice_custom_section_id?: string;
3863
+ invoice_custom_section: InvoiceCustomSectionObject;
3841
3864
  }
3842
3865
  /** Reference to a specific payment method for processing the payment. */
3843
3866
  export interface PaymentMethodReference {
@@ -7996,12 +8019,24 @@ export interface WalletTransactionObject {
7996
8019
  * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
7997
8020
  */
7998
8021
  lago_wallet_id: string;
8022
+ /**
8023
+ * Unique identifier assigned to the invoice associated with this wallet transaction. This ID is exclusively created by Lago and serves as a unique identifier for the invoice's record within the Lago system.
8024
+ * @format uuid
8025
+ * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
8026
+ */
8027
+ lago_invoice_id: string | null;
8028
+ /**
8029
+ * Unique identifier of the credit note associated with this wallet transaction. This ID is exclusively created by Lago and serves as a unique identifier for the invoice's record within the Lago system.
8030
+ * @format uuid
8031
+ * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
8032
+ */
8033
+ lago_credit_note_id: string | null;
7999
8034
  /**
8000
8035
  * Unique identifier of the invoice that was voided and triggered the creation of this inbound wallet transaction. Only present for inbound transactions on traceable wallets that were created as a result of an invoice void.
8001
8036
  * @format uuid
8002
8037
  * @example "1a901a90-1a90-1a90-1a90-1a901a901a90"
8003
8038
  */
8004
- lago_voided_invoice_id?: string | null;
8039
+ lago_voided_invoice_id: string | null;
8005
8040
  /**
8006
8041
  * The status of the wallet transaction. Possible values are `pending`, `settled` or `failed`.
8007
8042
  * @example "settled"
@@ -8038,12 +8073,12 @@ export interface WalletTransactionObject {
8038
8073
  * A boolean setting that, when set to true, delays issuing an invoice for a wallet top-up until a successful payment is made; if false, the invoice is issued immediately upon wallet top-up, regardless of the payment status. Default value of false.
8039
8074
  * @example false
8040
8075
  */
8041
- invoice_requires_successful_payment?: boolean;
8076
+ invoice_requires_successful_payment: boolean;
8042
8077
  /**
8043
8078
  * This field allows you to store a list of key-value pairs that hold additional information or custom attributes related to the data.
8044
8079
  * @example [{"key":"example key","value":"example value"},{"key":"another key","value":"another value"}]
8045
8080
  */
8046
- metadata?: {
8081
+ metadata: {
8047
8082
  /** The unique identifier for the attribute. */
8048
8083
  key?: string;
8049
8084
  /** The value associated with the key. */
@@ -8053,25 +8088,30 @@ export interface WalletTransactionObject {
8053
8088
  * The remaining unconsumed amount of an inbound wallet transaction, expressed in cents. Only present for inbound transactions on traceable wallets. Tracks how much of the original credited amount has not yet been consumed by outbound transactions.
8054
8089
  * @example 5000
8055
8090
  */
8056
- remaining_amount_cents?: number | null;
8091
+ remaining_amount_cents: number | null;
8057
8092
  /**
8058
8093
  * The remaining unconsumed amount of an inbound wallet transaction, expressed in credits. Only present for inbound transactions on traceable wallets.
8059
8094
  * @pattern ^[0-9]+.?[0-9]*$
8060
8095
  * @example "5.0"
8061
8096
  */
8062
- remaining_credit_amount?: string | null;
8097
+ remaining_credit_amount: string | null;
8098
+ /**
8099
+ * The priority of the wallet transaction, used to determine the order in which inbound transactions are consumed. Lower values are consumed first.
8100
+ * @example 50
8101
+ */
8102
+ priority: number;
8063
8103
  /**
8064
8104
  * The date when wallet transaction is settled, represented in ISO 8601 datetime format and expressed in Coordinated Universal Time (UTC).
8065
8105
  * @format date-time
8066
8106
  * @example "2022-04-29T08:59:51Z"
8067
8107
  */
8068
- settled_at?: string | null;
8108
+ settled_at: string | null;
8069
8109
  /**
8070
8110
  * The date when the wallet transaction failed, represented in ISO 8601 datetime format and expressed in Coordinated Universal Time (UTC).
8071
8111
  * @format date-time
8072
8112
  * @example "2022-04-29T08:59:51Z"
8073
8113
  */
8074
- failed_at?: string | null;
8114
+ failed_at: string | null;
8075
8115
  /**
8076
8116
  * The date of the wallet transaction creation, represented in ISO 8601 datetime format and expressed in Coordinated Universal Time (UTC).
8077
8117
  * @format date-time
@@ -8086,7 +8126,7 @@ export interface WalletTransactionObject {
8086
8126
  /** The invoice custom sections applied to invoices generated by this wallet transaction. */
8087
8127
  applied_invoice_custom_sections?: AppliedInvoiceCustomSectionObject[];
8088
8128
  /** The payment method assigned to this wallet transaction for processing the payment. */
8089
- payment_method?: PaymentMethodReference;
8129
+ payment_method: PaymentMethodReference;
8090
8130
  }
8091
8131
  export interface WalletTransactions {
8092
8132
  wallet_transactions: WalletTransactionObject[];
@@ -8753,7 +8793,7 @@ export declare class HttpClient<SecurityDataType = unknown> {
8753
8793
  }
8754
8794
  /**
8755
8795
  * @title Lago API documentation
8756
- * @version 1.44.0
8796
+ * @version 1.45.0
8757
8797
  * @license AGPLv3 (https://github.com/getlago/lago-openapi/blob/main/LICENSE)
8758
8798
  * @baseUrl https://api.getlago.com/api/v1
8759
8799
  * @externalDocs https://github.com/getlago
@@ -10288,7 +10328,9 @@ export declare class Api<SecurityDataType extends unknown> extends HttpClient<Se
10288
10328
  * @request POST:/customers/{external_customer_id}/checkout_url
10289
10329
  * @secure
10290
10330
  */
10291
- generateCustomerCheckoutUrl: (externalCustomerId: string, params?: RequestParams) => Promise<HttpResponse<CustomerCheckoutUrl, ApiErrorUnauthorized | ApiErrorUnprocessableEntity | ApiErrorNotFound>>;
10331
+ generateCustomerCheckoutUrl: (externalCustomerId: string, params?: RequestParams) => Promise<HttpResponse<{
10332
+ customer: CustomerCheckoutUrl;
10333
+ }, ApiErrorUnauthorized | ApiErrorUnprocessableEntity | ApiErrorNotFound>>;
10292
10334
  /**
10293
10335
  * @description This endpoint retrieves all payment methods of a Customer.
10294
10336
  *
@@ -152,7 +152,7 @@ class HttpClient {
152
152
  exports.HttpClient = HttpClient;
153
153
  /**
154
154
  * @title Lago API documentation
155
- * @version 1.44.0
155
+ * @version 1.45.0
156
156
  * @license AGPLv3 (https://github.com/getlago/lago-openapi/blob/main/LICENSE)
157
157
  * @baseUrl https://api.getlago.com/api/v1
158
158
  * @externalDocs https://github.com/getlago
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Error class for rate limit (HTTP 429) responses
3
+ */
4
+ export declare class LagoRateLimitError extends Error {
5
+ readonly limit: number;
6
+ readonly remaining: number;
7
+ readonly reset: number;
8
+ readonly retryAfter: number;
9
+ constructor(limit: number, remaining: number, reset: number);
10
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LagoRateLimitError = void 0;
4
+ /**
5
+ * Error class for rate limit (HTTP 429) responses
6
+ */
7
+ class LagoRateLimitError extends Error {
8
+ limit;
9
+ remaining;
10
+ reset; // seconds until window resets
11
+ retryAfter; // milliseconds to wait before retrying
12
+ constructor(limit, remaining, reset) {
13
+ super(`Rate limit exceeded. Limit: ${limit}, Remaining: ${remaining}, Reset in: ${reset}s`);
14
+ this.name = "LagoRateLimitError";
15
+ this.limit = limit;
16
+ this.remaining = remaining;
17
+ this.reset = reset;
18
+ this.retryAfter = reset * 1000; // Convert seconds to milliseconds
19
+ // Maintain proper prototype chain for instanceof checks
20
+ Object.setPrototypeOf(this, LagoRateLimitError.prototype);
21
+ }
22
+ }
23
+ exports.LagoRateLimitError = LagoRateLimitError;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Configuration for rate limit fetch behavior
3
+ */
4
+ export interface RateLimitFetchConfig {
5
+ /** Maximum number of retries on 429 (default: 3) */
6
+ maxRetries?: number;
7
+ /** Whether to automatically retry on rate limit (default: true) */
8
+ retryOnRateLimit?: boolean;
9
+ /** Maximum delay in milliseconds before a retry (default: 20000) */
10
+ maxRetryDelay?: number;
11
+ }
12
+ /**
13
+ * Creates a fetch wrapper that handles rate limiting with automatic retry
14
+ * Compatible with both Node.js fetch and browser fetch APIs
15
+ */
16
+ export declare function createRateLimitFetch(baseFetch: typeof fetch, config?: RateLimitFetchConfig): typeof fetch;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createRateLimitFetch = void 0;
4
+ const rate_limit_error_js_1 = require("./rate_limit_error.js");
5
+ const rate_limit_headers_js_1 = require("./rate_limit_headers.js");
6
+ /**
7
+ * Creates a fetch wrapper that handles rate limiting with automatic retry
8
+ * Compatible with both Node.js fetch and browser fetch APIs
9
+ */
10
+ function createRateLimitFetch(baseFetch, config = {}) {
11
+ const maxRetries = config.maxRetries ?? 3;
12
+ const retryOnRateLimit = config.retryOnRateLimit ?? true;
13
+ const maxRetryDelay = config.maxRetryDelay ?? 20_000;
14
+ return async function rateLimitFetch(input, init) {
15
+ let lastError;
16
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
17
+ try {
18
+ const response = await baseFetch(input, init);
19
+ // Handle 429 responses
20
+ if (response.status === 429) {
21
+ const headers = (0, rate_limit_headers_js_1.parseRateLimitHeaders)(response.headers);
22
+ const limit = headers.limit ?? -1;
23
+ const remaining = headers.remaining ?? 0;
24
+ const reset = headers.reset ?? -1;
25
+ const error = new rate_limit_error_js_1.LagoRateLimitError(limit, remaining, reset);
26
+ if (!retryOnRateLimit) {
27
+ throw error;
28
+ }
29
+ if (attempt === maxRetries) {
30
+ throw error; // Max retries reached
31
+ }
32
+ // Wait before retry
33
+ const waitMs = getWaitTime(error, attempt, maxRetryDelay);
34
+ await sleep(waitMs);
35
+ continue; // Retry
36
+ }
37
+ // Success or non-rate-limit error - return the response
38
+ return response;
39
+ }
40
+ catch (error) {
41
+ lastError = error;
42
+ if (!(error instanceof rate_limit_error_js_1.LagoRateLimitError)) {
43
+ throw error; // Not a rate limit error, rethrow immediately
44
+ }
45
+ if (attempt === maxRetries) {
46
+ throw error; // Max retries reached
47
+ }
48
+ // Will retry on next iteration
49
+ }
50
+ }
51
+ throw lastError;
52
+ };
53
+ }
54
+ exports.createRateLimitFetch = createRateLimitFetch;
55
+ /**
56
+ * Calculate wait time before retry
57
+ * Uses the exact reset time from headers if available, otherwise exponential backoff
58
+ */
59
+ function getWaitTime(error, attempt, maxRetryDelay) {
60
+ let waitMs;
61
+ if (error.reset > 0) {
62
+ // Use the exact reset time from the header
63
+ waitMs = error.retryAfter;
64
+ }
65
+ else {
66
+ // Exponential backoff: 1s, 2s, 4s, 8s, etc.
67
+ waitMs = 1000 * Math.pow(2, attempt);
68
+ }
69
+ // Cap at maxRetryDelay
70
+ waitMs = Math.min(waitMs, maxRetryDelay);
71
+ // Add small jitter to prevent thundering herd (max 100ms)
72
+ const jitter = Math.random() * 100;
73
+ return waitMs + jitter;
74
+ }
75
+ /**
76
+ * Sleep for a specified number of milliseconds
77
+ */
78
+ function sleep(ms) {
79
+ return new Promise((resolve) => setTimeout(resolve, ms));
80
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Parses rate limit headers from HTTP responses
3
+ */
4
+ export interface RateLimitHeaders {
5
+ limit: number | null;
6
+ remaining: number | null;
7
+ reset: number | null;
8
+ }
9
+ /**
10
+ * Extract rate limit information from response headers
11
+ */
12
+ export declare function parseRateLimitHeaders(headers: Headers): RateLimitHeaders;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseRateLimitHeaders = void 0;
4
+ /**
5
+ * Extract rate limit information from response headers
6
+ */
7
+ function parseRateLimitHeaders(headers) {
8
+ return {
9
+ limit: parseHeaderAsNumber(headers, "x-ratelimit-limit"),
10
+ remaining: parseHeaderAsNumber(headers, "x-ratelimit-remaining"),
11
+ reset: parseHeaderAsNumber(headers, "x-ratelimit-reset"),
12
+ };
13
+ }
14
+ exports.parseRateLimitHeaders = parseRateLimitHeaders;
15
+ /**
16
+ * Helper to parse a header value as a number
17
+ */
18
+ function parseHeaderAsNumber(headers, headerName) {
19
+ const value = headers.get(headerName);
20
+ if (value === null)
21
+ return null;
22
+ const num = parseInt(value, 10);
23
+ return isNaN(num) ? null : num;
24
+ }