orb-billing
Version:
The official TypeScript library for the Orb API
641 lines • 33.3 kB
JavaScript
"use strict";
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
var _Orb_instances, _a, _Orb_encoder, _Orb_baseURLOverridden;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Orb = void 0;
const tslib_1 = require("./internal/tslib.js");
const uuid_1 = require("./internal/utils/uuid.js");
const values_1 = require("./internal/utils/values.js");
const sleep_1 = require("./internal/utils/sleep.js");
const errors_1 = require("./internal/errors.js");
const detect_platform_1 = require("./internal/detect-platform.js");
const Shims = tslib_1.__importStar(require("./internal/shims.js"));
const Opts = tslib_1.__importStar(require("./internal/request-options.js"));
const query_1 = require("./internal/utils/query.js");
const version_1 = require("./version.js");
const Errors = tslib_1.__importStar(require("./core/error.js"));
const Pagination = tslib_1.__importStar(require("./core/pagination.js"));
const Uploads = tslib_1.__importStar(require("./core/uploads.js"));
const API = tslib_1.__importStar(require("./resources/index.js"));
const api_promise_1 = require("./core/api-promise.js");
const alerts_1 = require("./resources/alerts.js");
const credit_blocks_1 = require("./resources/credit-blocks.js");
const credit_notes_1 = require("./resources/credit-notes.js");
const invoice_line_items_1 = require("./resources/invoice-line-items.js");
const invoices_1 = require("./resources/invoices.js");
const items_1 = require("./resources/items.js");
const license_types_1 = require("./resources/license-types.js");
const metrics_1 = require("./resources/metrics.js");
const subscription_changes_1 = require("./resources/subscription-changes.js");
const top_level_1 = require("./resources/top-level.js");
const webhooks_1 = require("./resources/webhooks.js");
const beta_1 = require("./resources/beta/beta.js");
const coupons_1 = require("./resources/coupons/coupons.js");
const customers_1 = require("./resources/customers/customers.js");
const events_1 = require("./resources/events/events.js");
const licenses_1 = require("./resources/licenses/licenses.js");
const plans_1 = require("./resources/plans/plans.js");
const prices_1 = require("./resources/prices/prices.js");
const headers_1 = require("./internal/headers.js");
const env_1 = require("./internal/utils/env.js");
const log_1 = require("./internal/utils/log.js");
const values_2 = require("./internal/utils/values.js");
/**
* API Client for interfacing with the Orb API.
*/
class Orb {
/**
* API Client for interfacing with the Orb API.
*
* @param {string | undefined} [opts.apiKey=process.env['ORB_API_KEY'] ?? undefined]
* @param {string | null | undefined} [opts.webhookSecret=process.env['ORB_WEBHOOK_SECRET'] ?? null]
* @param {string} [opts.baseURL=process.env['ORB_BASE_URL'] ?? https://api.withorb.com/v1] - Override the default base URL for the API.
* @param {number} [opts.timeout=1 minute] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
* @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls.
* @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
* @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
* @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API.
* @param {Record<string, string | undefined>} opts.defaultQuery - Default query parameters to include with every request to the API.
*/
constructor({ baseURL = (0, env_1.readEnv)('ORB_BASE_URL'), apiKey = (0, env_1.readEnv)('ORB_API_KEY'), webhookSecret = (0, env_1.readEnv)('ORB_WEBHOOK_SECRET') ?? null, ...opts } = {}) {
_Orb_instances.add(this);
_Orb_encoder.set(this, void 0);
this.topLevel = new API.TopLevel(this);
/**
* The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
* customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
* in the [Price resource](/reference/price).
*/
this.beta = new API.Beta(this);
/**
* A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
*/
this.coupons = new API.Coupons(this);
/**
* The [Credit Note](/invoicing/credit-notes) resource represents a credit that has been applied to a
* particular invoice.
*/
this.creditNotes = new API.CreditNotes(this);
/**
* A customer is a buyer of your products, and the other party to the billing relationship.
*
* In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
* match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
* `external_customer_id` with your own identifier. See
* [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
* aliases work in Orb.
*
* In addition to having an identifier in your system, a customer may exist in a payment provider solution like
* Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
*
* A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
* defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
* information on what this timezone parameter influences within Orb.
*/
this.customers = new API.Customers(this);
/**
* The [Event](/core-concepts#event) resource represents a usage event that has been created for a
* customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
* a given billing period.
*/
this.events = new API.Events(this);
/**
* An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
* a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
* can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
* the result of an action, such as a cancellation.
*/
this.invoiceLineItems = new API.InvoiceLineItems(this);
/**
* An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
* a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
* can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
* the result of an action, such as a cancellation.
*/
this.invoices = new API.Invoices(this);
/**
* The Item resource represents a sellable product or good. Items are associated with all line items, billable metrics,
* and prices and are used for defining external sync behavior for invoices and tax calculation purposes.
*/
this.items = new API.Items(this);
/**
* The Metric resource represents a calculation of a quantity based on events.
* Metrics are defined by the query that transforms raw usage events into meaningful values for your customers.
*/
this.metrics = new API.Metrics(this);
/**
* The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
* customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
* in the [Price resource](/reference/price).
*/
this.plans = new API.Plans(this);
/**
* The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
* the form of an invoice line item. Prices take a quantity and determine an amount to bill.
*
* Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
* given Price object. The model_type field determines the key for the configuration object that is present.
*
* For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
*/
this.prices = new API.Prices(this);
this.subscriptions = new API.Subscriptions(this);
/**
* [Alerts within Orb](/product-catalog/configuring-alerts) monitor spending,
* usage, or credit balance and trigger webhooks when a threshold is exceeded.
*
* Alerts created through the API can be scoped to either customers or subscriptions.
*/
this.alerts = new API.Alerts(this);
this.dimensionalPriceGroups = new API.DimensionalPriceGroups(this);
this.subscriptionChanges = new API.SubscriptionChanges(this);
/**
* The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
*/
this.creditBlocks = new API.CreditBlocks(this);
/**
* The LicenseType resource represents a type of license that can be assigned to users.
* License types are used during billing by grouping metrics on the configured grouping key.
*/
this.licenseTypes = new API.LicenseTypes(this);
this.licenses = new API.Licenses(this);
this.webhooks = new API.Webhooks(this);
if (apiKey === undefined) {
throw new Errors.OrbError("The ORB_API_KEY environment variable is missing or empty; either provide it, or instantiate the Orb client with an apiKey option, like new Orb({ apiKey: 'My API Key' }).");
}
const options = {
apiKey,
webhookSecret,
...opts,
baseURL: baseURL || `https://api.withorb.com/v1`,
};
this.baseURL = options.baseURL;
this.timeout = options.timeout ?? _a.DEFAULT_TIMEOUT /* 1 minute */;
this.logger = options.logger ?? console;
const defaultLogLevel = 'warn';
// Set default logLevel early so that we can log a warning in parseLogLevel.
this.logLevel = defaultLogLevel;
this.logLevel =
(0, log_1.parseLogLevel)(options.logLevel, 'ClientOptions.logLevel', this) ??
(0, log_1.parseLogLevel)((0, env_1.readEnv)('ORB_LOG'), "process.env['ORB_LOG']", this) ??
defaultLogLevel;
this.fetchOptions = options.fetchOptions;
this.maxRetries = options.maxRetries ?? 2;
this.fetch = options.fetch ?? Shims.getDefaultFetch();
tslib_1.__classPrivateFieldSet(this, _Orb_encoder, Opts.FallbackEncoder, "f");
const customHeadersEnv = (0, env_1.readEnv)('ORB_CUSTOM_HEADERS');
if (customHeadersEnv) {
const parsed = {};
for (const line of customHeadersEnv.split('\n')) {
const colon = line.indexOf(':');
if (colon >= 0) {
parsed[line.substring(0, colon).trim()] = line.substring(colon + 1).trim();
}
}
options.defaultHeaders = { ...parsed, ...options.defaultHeaders };
}
this._options = options;
this.idempotencyHeader = 'Idempotency-Key';
this.apiKey = apiKey;
this.webhookSecret = webhookSecret;
}
/**
* Create a new client instance re-using the same options given to the current client with optional overriding.
*/
withOptions(options) {
const client = new this.constructor({
...this._options,
baseURL: this.baseURL,
maxRetries: this.maxRetries,
timeout: this.timeout,
logger: this.logger,
logLevel: this.logLevel,
fetch: this.fetch,
fetchOptions: this.fetchOptions,
apiKey: this.apiKey,
webhookSecret: this.webhookSecret,
...options,
});
return client;
}
defaultQuery() {
return this._options.defaultQuery;
}
validateHeaders({ values, nulls }) {
return;
}
async authHeaders(opts) {
return (0, headers_1.buildHeaders)([{ Authorization: `Bearer ${this.apiKey}` }]);
}
stringifyQuery(query) {
return (0, query_1.stringifyQuery)(query);
}
getUserAgent() {
return `${this.constructor.name}/JS ${version_1.VERSION}`;
}
defaultIdempotencyKey() {
return `stainless-node-retry-${(0, uuid_1.uuid4)()}`;
}
makeStatusError(status, error, message, headers) {
return Errors.APIError.generate(status, error, message, headers);
}
buildURL(path, query, defaultBaseURL) {
const baseURL = (!tslib_1.__classPrivateFieldGet(this, _Orb_instances, "m", _Orb_baseURLOverridden).call(this) && defaultBaseURL) || this.baseURL;
const url = (0, values_1.isAbsoluteURL)(path) ?
new URL(path)
: new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
const defaultQuery = this.defaultQuery();
const pathQuery = Object.fromEntries(url.searchParams);
if (!(0, values_2.isEmptyObj)(defaultQuery) || !(0, values_2.isEmptyObj)(pathQuery)) {
query = { ...pathQuery, ...defaultQuery, ...query };
}
if (typeof query === 'object' && query && !Array.isArray(query)) {
url.search = this.stringifyQuery(query);
}
return url.toString();
}
/**
* Used as a callback for mutating the given `FinalRequestOptions` object.
*/
async prepareOptions(options) { }
/**
* Used as a callback for mutating the given `RequestInit` object.
*
* This is useful for cases where you want to add certain headers based off of
* the request properties, e.g. `method` or `url`.
*/
async prepareRequest(request, { url, options }) { }
get(path, opts) {
return this.methodRequest('get', path, opts);
}
post(path, opts) {
return this.methodRequest('post', path, opts);
}
patch(path, opts) {
return this.methodRequest('patch', path, opts);
}
put(path, opts) {
return this.methodRequest('put', path, opts);
}
delete(path, opts) {
return this.methodRequest('delete', path, opts);
}
methodRequest(method, path, opts) {
return this.request(Promise.resolve(opts).then((opts) => {
return { method, path, ...opts };
}));
}
request(options, remainingRetries = null) {
return new api_promise_1.APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
}
async makeRequest(optionsInput, retriesRemaining, retryOfRequestLogID) {
const options = await optionsInput;
const maxRetries = options.maxRetries ?? this.maxRetries;
if (retriesRemaining == null) {
retriesRemaining = maxRetries;
}
await this.prepareOptions(options);
const { req, url, timeout } = await this.buildRequest(options, {
retryCount: maxRetries - retriesRemaining,
});
await this.prepareRequest(req, { url, options });
/** Not an API request ID, just for correlating local log entries. */
const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0');
const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
const startTime = Date.now();
(0, log_1.loggerFor)(this).debug(`[${requestLogID}] sending request`, (0, log_1.formatRequestDetails)({
retryOfRequestLogID,
method: options.method,
url,
options,
headers: req.headers,
}));
if (options.signal?.aborted) {
throw new Errors.APIUserAbortError();
}
const controller = new AbortController();
const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(errors_1.castToError);
const headersTime = Date.now();
if (response instanceof globalThis.Error) {
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
if (options.signal?.aborted) {
throw new Errors.APIUserAbortError();
}
// detect native connection timeout errors
// deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)"
// undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
// others do not provide enough information to distinguish timeouts from other connection errors
const isTimeout = (0, errors_1.isAbortError)(response) ||
/timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));
if (retriesRemaining) {
(0, log_1.loggerFor)(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`);
(0, log_1.loggerFor)(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`, (0, log_1.formatRequestDetails)({
retryOfRequestLogID,
url,
durationMs: headersTime - startTime,
message: response.message,
}));
return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID);
}
(0, log_1.loggerFor)(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`);
(0, log_1.loggerFor)(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`, (0, log_1.formatRequestDetails)({
retryOfRequestLogID,
url,
durationMs: headersTime - startTime,
message: response.message,
}));
if (isTimeout) {
throw new Errors.APIConnectionTimeoutError();
}
throw new Errors.APIConnectionError({ cause: response });
}
const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${response.ok ? 'succeeded' : 'failed'} with status ${response.status} in ${headersTime - startTime}ms`;
if (!response.ok) {
const shouldRetry = await this.shouldRetry(response);
if (retriesRemaining && shouldRetry) {
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
// We don't need the body of this response.
await Shims.CancelReadableStream(response.body);
(0, log_1.loggerFor)(this).info(`${responseInfo} - ${retryMessage}`);
(0, log_1.loggerFor)(this).debug(`[${requestLogID}] response error (${retryMessage})`, (0, log_1.formatRequestDetails)({
retryOfRequestLogID,
url: response.url,
status: response.status,
headers: response.headers,
durationMs: headersTime - startTime,
}));
return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID, response.headers);
}
const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
(0, log_1.loggerFor)(this).info(`${responseInfo} - ${retryMessage}`);
const errText = await response.text().catch((err) => (0, errors_1.castToError)(err).message);
const errJSON = (0, values_1.safeJSON)(errText);
const errMessage = errJSON ? undefined : errText;
(0, log_1.loggerFor)(this).debug(`[${requestLogID}] response error (${retryMessage})`, (0, log_1.formatRequestDetails)({
retryOfRequestLogID,
url: response.url,
status: response.status,
headers: response.headers,
message: errMessage,
durationMs: Date.now() - startTime,
}));
const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
throw err;
}
(0, log_1.loggerFor)(this).info(responseInfo);
(0, log_1.loggerFor)(this).debug(`[${requestLogID}] response start`, (0, log_1.formatRequestDetails)({
retryOfRequestLogID,
url: response.url,
status: response.status,
headers: response.headers,
durationMs: headersTime - startTime,
}));
return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
}
getAPIList(path, Page, opts) {
return this.requestAPIList(Page, opts && 'then' in opts ?
opts.then((opts) => ({ method: 'get', path, ...opts }))
: { method: 'get', path, ...opts });
}
requestAPIList(Page, options) {
const request = this.makeRequest(options, null, undefined);
return new Pagination.PagePromise(this, request, Page);
}
async fetchWithTimeout(url, init, ms, controller) {
const { signal, method, ...options } = init || {};
const abort = this._makeAbort(controller);
if (signal)
signal.addEventListener('abort', abort, { once: true });
const timeout = setTimeout(abort, ms);
const isReadableBody = (globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream) ||
(typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
const fetchOptions = {
signal: controller.signal,
...(isReadableBody ? { duplex: 'half' } : {}),
method: 'GET',
...options,
};
if (method) {
// Custom methods like 'patch' need to be uppercased
// See https://github.com/nodejs/undici/issues/2294
fetchOptions.method = method.toUpperCase();
}
try {
// use undefined this binding; fetch errors if bound to something else in browser/cloudflare
return await this.fetch.call(undefined, url, fetchOptions);
}
finally {
clearTimeout(timeout);
}
}
async shouldRetry(response) {
// Note this is not a standard header.
const shouldRetryHeader = response.headers.get('x-should-retry');
// If the server explicitly says whether or not to retry, obey.
if (shouldRetryHeader === 'true')
return true;
if (shouldRetryHeader === 'false')
return false;
// Retry on request timeouts.
if (response.status === 408)
return true;
// Retry on lock timeouts.
if (response.status === 409)
return true;
// Retry on rate limits.
if (response.status === 429)
return true;
// Retry internal errors.
if (response.status >= 500)
return true;
return false;
}
async retryRequest(options, retriesRemaining, requestLogID, responseHeaders) {
let timeoutMillis;
// Note the `retry-after-ms` header may not be standard, but is a good idea and we'd like proactive support for it.
const retryAfterMillisHeader = responseHeaders?.get('retry-after-ms');
if (retryAfterMillisHeader) {
const timeoutMs = parseFloat(retryAfterMillisHeader);
if (!Number.isNaN(timeoutMs)) {
timeoutMillis = timeoutMs;
}
}
// About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
const retryAfterHeader = responseHeaders?.get('retry-after');
if (retryAfterHeader && !timeoutMillis) {
const timeoutSeconds = parseFloat(retryAfterHeader);
if (!Number.isNaN(timeoutSeconds)) {
timeoutMillis = timeoutSeconds * 1000;
}
else {
timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
}
}
// If the API asks us to wait a certain amount of time, just do what it
// says, but otherwise calculate a default
if (timeoutMillis === undefined) {
const maxRetries = options.maxRetries ?? this.maxRetries;
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
}
await (0, sleep_1.sleep)(timeoutMillis);
return this.makeRequest(options, retriesRemaining - 1, requestLogID);
}
calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
const initialRetryDelay = 0.5;
const maxRetryDelay = 8.0;
const numRetries = maxRetries - retriesRemaining;
// Apply exponential backoff, but not more than the max.
const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);
// Apply some jitter, take up to at most 25 percent of the retry time.
const jitter = 1 - Math.random() * 0.25;
return sleepSeconds * jitter * 1000;
}
async buildRequest(inputOptions, { retryCount = 0 } = {}) {
const options = { ...inputOptions };
const { method, path, query, defaultBaseURL } = options;
const url = this.buildURL(path, query, defaultBaseURL);
if ('timeout' in options)
(0, values_1.validatePositiveInteger)('timeout', options.timeout);
options.timeout = options.timeout ?? this.timeout;
const { bodyHeaders, body } = this.buildBody({ options });
const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
const req = {
method,
headers: reqHeaders,
...(options.signal && { signal: options.signal }),
...(globalThis.ReadableStream &&
body instanceof globalThis.ReadableStream && { duplex: 'half' }),
...(body && { body }),
...(this.fetchOptions ?? {}),
...(options.fetchOptions ?? {}),
};
return { req, url, timeout: options.timeout };
}
async buildHeaders({ options, method, bodyHeaders, retryCount, }) {
let idempotencyHeaders = {};
if (this.idempotencyHeader && method !== 'get') {
if (!options.idempotencyKey)
options.idempotencyKey = this.defaultIdempotencyKey();
idempotencyHeaders[this.idempotencyHeader] = options.idempotencyKey;
}
const headers = (0, headers_1.buildHeaders)([
idempotencyHeaders,
{
Accept: 'application/json',
'User-Agent': this.getUserAgent(),
'X-Stainless-Retry-Count': String(retryCount),
...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}),
...(0, detect_platform_1.getPlatformHeaders)(),
},
await this.authHeaders(options),
this._options.defaultHeaders,
bodyHeaders,
options.headers,
]);
this.validateHeaders(headers);
return headers.values;
}
_makeAbort(controller) {
// note: we can't just inline this method inside `fetchWithTimeout()` because then the closure
// would capture all request options, and cause a memory leak.
return () => controller.abort();
}
buildBody({ options }) {
const { body, headers: rawHeaders } = options;
if (!body) {
// A resource method always passes a `body` key when its operation defines a
// request body, even if the caller omitted an optional body param. Keep the
// content-type for those, and only elide it for operations with no body at
// all (e.g. GET/DELETE).
if (body == null && 'body' in options) {
return tslib_1.__classPrivateFieldGet(this, _Orb_encoder, "f").call(this, { body, headers: (0, headers_1.buildHeaders)([rawHeaders]) });
}
return { bodyHeaders: undefined, body: undefined };
}
const headers = (0, headers_1.buildHeaders)([rawHeaders]);
if (
// Pass raw type verbatim
ArrayBuffer.isView(body) ||
body instanceof ArrayBuffer ||
body instanceof DataView ||
(typeof body === 'string' &&
// Preserve legacy string encoding behavior for now
headers.values.has('content-type')) ||
// `Blob` is superset of `File`
(globalThis.Blob && body instanceof globalThis.Blob) ||
// `FormData` -> `multipart/form-data`
body instanceof FormData ||
// `URLSearchParams` -> `application/x-www-form-urlencoded`
body instanceof URLSearchParams ||
// Send chunked stream (each chunk has own `length`)
(globalThis.ReadableStream && body instanceof globalThis.ReadableStream)) {
return { bodyHeaders: undefined, body: body };
}
else if (typeof body === 'object' &&
(Symbol.asyncIterator in body ||
(Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) {
return { bodyHeaders: undefined, body: Shims.ReadableStreamFrom(body) };
}
else if (typeof body === 'object' &&
headers.values.get('content-type') === 'application/x-www-form-urlencoded') {
return {
bodyHeaders: { 'content-type': 'application/x-www-form-urlencoded' },
body: this.stringifyQuery(body),
};
}
else {
return tslib_1.__classPrivateFieldGet(this, _Orb_encoder, "f").call(this, { body, headers });
}
}
}
exports.Orb = Orb;
_a = Orb, _Orb_encoder = new WeakMap(), _Orb_instances = new WeakSet(), _Orb_baseURLOverridden = function _Orb_baseURLOverridden() {
return this.baseURL !== 'https://api.withorb.com/v1';
};
Orb.Orb = _a;
Orb.DEFAULT_TIMEOUT = 60000; // 1 minute
Orb.OrbError = Errors.OrbError;
Orb.APIError = Errors.APIError;
Orb.APIConnectionError = Errors.APIConnectionError;
Orb.APIConnectionTimeoutError = Errors.APIConnectionTimeoutError;
Orb.APIUserAbortError = Errors.APIUserAbortError;
Orb.URLNotFound = Errors.URLNotFound;
Orb.NotFoundError = Errors.NotFoundError;
Orb.ConflictError = Errors.ConflictError;
Orb.RateLimitError = Errors.RateLimitError;
Orb.BadRequestError = Errors.BadRequestError;
Orb.RequestTooLarge = Errors.RequestTooLarge;
Orb.TooManyRequests = Errors.TooManyRequests;
Orb.ResourceNotFound = Errors.ResourceNotFound;
Orb.ResourceConflict = Errors.ResourceConflict;
Orb.ResourceTooLarge = Errors.ResourceTooLarge;
Orb.AuthenticationError = Errors.AuthenticationError;
Orb.InternalServerError = Errors.InternalServerError;
Orb.ConstraintViolation = Errors.ConstraintViolation;
Orb.FeatureNotAvailable = Errors.FeatureNotAvailable;
Orb.PermissionDeniedError = Errors.PermissionDeniedError;
Orb.RequestValidationError = Errors.RequestValidationError;
Orb.OrbAuthenticationError = Errors.OrbAuthenticationError;
Orb.OrbInternalServerError = Errors.OrbInternalServerError;
Orb.UnprocessableEntityError = Errors.UnprocessableEntityError;
Orb.DuplicateResourceCreation = Errors.DuplicateResourceCreation;
Orb.toFile = Uploads.toFile;
Orb.TopLevel = top_level_1.TopLevel;
Orb.Beta = beta_1.Beta;
Orb.Coupons = coupons_1.Coupons;
Orb.CreditNotes = credit_notes_1.CreditNotes;
Orb.Customers = customers_1.Customers;
Orb.Events = events_1.Events;
Orb.InvoiceLineItems = invoice_line_items_1.InvoiceLineItems;
Orb.Invoices = invoices_1.Invoices;
Orb.Items = items_1.Items;
Orb.Metrics = metrics_1.Metrics;
Orb.Plans = plans_1.Plans;
Orb.Prices = prices_1.Prices;
Orb.Alerts = alerts_1.Alerts;
Orb.SubscriptionChanges = subscription_changes_1.SubscriptionChanges;
Orb.CreditBlocks = credit_blocks_1.CreditBlocks;
Orb.LicenseTypes = license_types_1.LicenseTypes;
Orb.Licenses = licenses_1.Licenses;
Orb.Webhooks = webhooks_1.Webhooks;
//# sourceMappingURL=client.js.map