UNPKG

autumn-js

Version:

Autumn JS Library

1,214 lines (1,179 loc) 31.9 kB
"use client"; "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/libraries/react/index.ts var index_exports = {}; __export(index_exports, { AutumnProvider: () => ReactAutumnProvider, useAutumn: () => useAutumn, useCustomer: () => useCustomer, useEntity: () => useEntity, usePricingTable: () => usePricingTable }); module.exports = __toCommonJS(index_exports); // src/libraries/react/AutumnContext.tsx var import_react = require("react"); // src/sdk/error.ts var AutumnError = class extends Error { message; code; constructor(response) { super(response.message); this.message = response.message; this.code = response.code; } toString() { return `${this.message} (code: ${this.code})`; } toJSON() { return { message: this.message, code: this.code }; } }; // src/sdk/utils.ts var staticWrapper = (callback, instance, args) => { if (!instance) { instance = new Autumn(); } return callback({ instance, ...args }); }; // src/sdk/customers/cusMethods.ts var customerMethods = (instance) => { return { get: (id, params) => staticWrapper(getCustomer, instance, { id, params }), create: (params) => staticWrapper(createCustomer, instance, { params }), update: (id, params) => staticWrapper(updateCustomer, instance, { id, params }), delete: (id) => staticWrapper(deleteCustomer, instance, { id }), billingPortal: (id, params) => staticWrapper(billingPortal, instance, { id, params }) }; }; var getExpandStr = (expand) => { if (!expand) { return ""; } return `expand=${expand.join(",")}`; }; var getCustomer = async ({ instance, id, params }) => { if (!id) { return { data: null, error: new AutumnError({ message: "Customer ID is required", code: "CUSTOMER_ID_REQUIRED" }) }; } return instance.get(`/customers/${id}?${getExpandStr(params?.expand)}`); }; var createCustomer = async ({ instance, params }) => { return instance.post(`/customers?${getExpandStr(params?.expand)}`, params); }; var updateCustomer = async ({ instance, id, params }) => { return instance.post(`/customers/${id}`, params); }; var deleteCustomer = async ({ instance, id }) => { return instance.delete(`/customers/${id}`); }; var billingPortal = async ({ instance, id, params }) => { return instance.post(`/customers/${id}/billing_portal`, params); }; // src/sdk/customers/entities/entMethods.ts var entityMethods = (instance) => { return { get: (customer_id, entity_id, params) => staticWrapper(getEntity, instance, { customer_id, entity_id, params }), create: (customer_id, params) => staticWrapper(createEntity, instance, { customer_id, params }), delete: (customer_id, entity_id) => staticWrapper(deleteEntity, instance, { customer_id, entity_id }) }; }; var getExpandStr2 = (expand) => { if (!expand) { return ""; } return `expand=${expand.join(",")}`; }; var getEntity = async ({ instance, customer_id, entity_id, params }) => { return instance.get( `/customers/${customer_id}/entities/${entity_id}?${getExpandStr2( params?.expand )}` ); }; var createEntity = async ({ instance, customer_id, params }) => { return instance.post(`/customers/${customer_id}/entities`, params); }; var deleteEntity = async ({ instance, customer_id, entity_id }) => { return instance.delete(`/customers/${customer_id}/entities/${entity_id}`); }; // src/sdk/general/genMethods.ts var handleAttach = async ({ instance, params }) => { return instance.post("/attach", params); }; var handleCancel = async ({ instance, params }) => { return instance.post("/cancel", params); }; var handleEntitled = async ({ instance, params }) => { return instance.post("/entitled", params); }; var handleEvent = async ({ instance, params }) => { return instance.post("/events", params); }; var handleTrack = async ({ instance, params }) => { return instance.post("/track", params); }; var handleUsage = async ({ instance, params }) => { return instance.post("/usage", params); }; var handleCheck = async ({ instance, params }) => { return instance.post("/check", params); }; // src/sdk/products/prodMethods.ts var productMethods = (instance) => { return { get: (id) => staticWrapper(getProduct, instance, { id }), create: (params) => staticWrapper(createProduct, instance, { params }), list: (params) => staticWrapper(listProducts, instance, { params }) }; }; var listProducts = async ({ instance, params }) => { let path = "/products"; if (params) { const queryParams = new URLSearchParams(); for (const [key, value] of Object.entries(params)) { if (value !== void 0) { queryParams.append(key, String(value)); } } const queryString = queryParams.toString(); if (queryString) { path += `?${queryString}`; } } return instance.get(path); }; var getProduct = async ({ instance, id }) => { return instance.get(`/products/${id}`); }; var createProduct = async ({ instance, params }) => { return instance.post("/products", params); }; // src/sdk/referrals/referralMethods.ts var referralMethods = (instance) => { return { createCode: (params) => staticWrapper(createReferralCode, instance, { params }), redeemCode: (params) => staticWrapper(redeemReferralCode, instance, { params }) }; }; var createReferralCode = async ({ instance, params }) => { return instance.post("/referrals/code", params); }; var redeemReferralCode = async ({ instance, params }) => { return instance.post("/referrals/redeem", params); }; // src/sdk/response.ts var toContainerResult = async (response) => { if (response.status < 200 || response.status >= 300) { let error; try { error = await response.json(); } catch (error2) { return { data: null, error: new AutumnError({ message: "Failed to parse JSON response from Autumn", code: "internal_error" }), statusCode: response.status }; } return { data: null, error: new AutumnError({ message: error.message, code: error.code }), statusCode: response.status }; } try { let data = await response.json(); return { data, error: null, statusCode: response?.status }; } catch (error) { return { data: null, error: new AutumnError({ message: "Failed to parse Autumn API response", code: "internal_error" }), statusCode: response?.status }; } }; // src/sdk/client.ts var LATEST_API_VERSION = "1.2"; var Autumn = class { secretKey; publishableKey; level; headers; url; constructor(options) { try { this.secretKey = options?.secretKey || process.env.AUTUMN_SECRET_KEY; this.publishableKey = options?.publishableKey || process.env.AUTUMN_PUBLISHABLE_KEY; } catch (error) { } if (!this.secretKey && !this.publishableKey && !options?.headers) { throw new Error("Autumn secret key or publishable key is required"); } this.headers = options?.headers || { Authorization: `Bearer ${this.secretKey || this.publishableKey}`, "Content-Type": "application/json" }; let version = options?.version || LATEST_API_VERSION; this.headers["x-api-version"] = version; this.url = options?.url || "https://api.useautumn.com/v1"; this.level = this.secretKey ? "secret" : "publishable"; } getLevel() { return this.level; } async get(path) { const response = await fetch(`${this.url}${path}`, { headers: this.headers }); return toContainerResult(response); } async post(path, body) { try { const response = await fetch(`${this.url}${path}`, { method: "POST", headers: this.headers, body: JSON.stringify(body) }); return toContainerResult(response); } catch (error) { console.error("Error sending request:", error); throw error; } } async delete(path) { const response = await fetch(`${this.url}${path}`, { method: "DELETE", headers: this.headers }); return toContainerResult(response); } static customers = customerMethods(); static products = productMethods(); static entities = entityMethods(); static referrals = referralMethods(); customers = customerMethods(this); products = productMethods(this); entities = entityMethods(this); referrals = referralMethods(this); static attach = (params) => staticWrapper(handleAttach, void 0, { params }); static usage = (params) => staticWrapper(handleUsage, void 0, { params }); async attach(params) { return handleAttach({ instance: this, params }); } static cancel = (params) => staticWrapper(handleCancel, void 0, { params }); async cancel(params) { return handleCancel({ instance: this, params }); } /** * @deprecated This method is deprecated and will be removed in a future version. * Please use the new check() method instead. */ static entitled = (params) => staticWrapper(handleEntitled, void 0, { params }); /** * @deprecated This method is deprecated and will be removed in a future version. * Please use the new check() method instead. */ async entitled(params) { return handleEntitled({ instance: this, params }); } static check = (params) => staticWrapper(handleCheck, void 0, { params }); async check(params) { return handleCheck({ instance: this, params }); } /** * @deprecated This method is deprecated and will be removed in a future version. * Please use the new track() method instead. */ static event = (params) => staticWrapper(handleEvent, void 0, { params }); /** * @deprecated This method is deprecated and will be removed in a future version. * Please use the new track() method instead. */ async event(params) { return handleEvent({ instance: this, params }); } static track = (params) => staticWrapper(handleTrack, void 0, { params }); async track(params) { return handleTrack({ instance: this, params }); } async usage(params) { return handleUsage({ instance: this, params }); } }; // src/libraries/react/client/clientCompMethods.ts async function getPricingTableMethod() { const res = await this.get("/api/autumn/components/pricing_table"); return res; } // src/libraries/react/client/clientCusMethods.ts var createCustomerMethod = async ({ client, params }) => { let result = await client.post("/api/autumn/customers", params); return result; }; // src/libraries/react/utils/toSnakeCase.ts function stringToSnakeCase(str) { return str.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[-\s]+/g, "_").toLowerCase(); } var toSnakeCase = (obj) => { if (Array.isArray(obj)) { return obj.map(toSnakeCase); } else if (obj !== null && typeof obj === "object") { return Object.fromEntries( Object.entries(obj).map(([key, value]) => [ stringToSnakeCase(key), toSnakeCase(value) ]) ); } return obj; }; // src/utils/entityUtils.tsx var getEntityExpandStr = (expand) => { if (!expand) { return ""; } return `expand=${expand.join(",")}`; }; // src/libraries/react/client/clientEntityMethods.ts async function createEntityMethod(params) { let snakeParams = toSnakeCase(params); const res = await this.post("/api/autumn/entities", snakeParams); return res; } async function getEntityMethod(entityId, params) { let snakeParams = toSnakeCase(params); let expand = getEntityExpandStr(params?.expand); const res = await this.get(`/api/autumn/entities/${entityId}?${expand}`); return res; } async function deleteEntityMethod(entityId) { const res = await this.delete(`/api/autumn/entities/${entityId}`); return res; } // src/libraries/react/client/clientGenMethods.ts async function attachMethod(params) { let { dialog, ...rest } = params; let snakeParams = toSnakeCase(rest); const res = await this.post("/api/autumn/attach", snakeParams); return res; } async function cancelMethod(params) { let snakeParams = toSnakeCase(params); const res = await this.post("/api/autumn/cancel", snakeParams); return res; } async function checkMethod(params) { let { dialog, ...rest } = params; let snakeParams = toSnakeCase(rest); const res = await this.post("/api/autumn/check", snakeParams); return res; } async function trackMethod(params) { let snakeParams = toSnakeCase(params); const res = await this.post("/api/autumn/track", snakeParams); return res; } async function openBillingPortalMethod(params) { let snakeParams = toSnakeCase(params || {}); const res = await this.post("/api/autumn/billing_portal", snakeParams); return res; } // src/libraries/react/client/clientReferralMethods.ts async function createCode(params) { let snakeParams = toSnakeCase(params); const res = await this.post("/api/autumn/referrals/code", snakeParams); return res; } async function redeemCode(params) { let snakeParams = toSnakeCase(params); const res = await this.post("/api/autumn/referrals/redeem", snakeParams); return res; } // src/libraries/react/client/ReactAutumnClient.tsx var AutumnClient = class { backendUrl; getBearerToken; customerData; includeCredentials; constructor({ backendUrl, getBearerToken, customerData, includeCredentials }) { this.backendUrl = backendUrl; this.getBearerToken = getBearerToken; this.customerData = customerData; this.includeCredentials = includeCredentials; } async getHeaders() { let headers = { "Content-Type": "application/json" }; if (this.getBearerToken) { try { let token = await this.getBearerToken(); headers.Authorization = `Bearer ${token}`; } catch (error) { console.error(`Failed to call getToken() in AutumnProvider`); } } return headers; } async handleFetchResult(result) { let res = await toContainerResult(result); return res; } async post(path, body) { const response = await fetch(`${this.backendUrl}${path}`, { method: "POST", body: JSON.stringify({ ...body, customer_data: this.customerData || void 0 }), headers: await this.getHeaders(), credentials: this.includeCredentials ? "include" : void 0 }); return await this.handleFetchResult(response); } async get(path) { const response = await fetch(`${this.backendUrl}${path}`, { method: "GET", headers: await this.getHeaders(), credentials: this.includeCredentials ? "include" : void 0 }); return await this.handleFetchResult(response); } async delete(path) { const response = await fetch(`${this.backendUrl}${path}`, { method: "DELETE", headers: await this.getHeaders() }); return await this.handleFetchResult(response); } async createCustomer(params) { return await createCustomerMethod({ client: this, params }); } async getPricingTable() { return await getPricingTableMethod.bind(this)(); } attach = attachMethod.bind(this); cancel = cancelMethod.bind(this); check = checkMethod.bind(this); track = trackMethod.bind(this); openBillingPortal = openBillingPortalMethod.bind(this); entities = { create: createEntityMethod.bind(this), get: getEntityMethod.bind(this), delete: deleteEntityMethod.bind(this) }; referrals = { createCode: createCode.bind(this), redeemCode: redeemCode.bind(this) }; }; // src/libraries/react/AutumnContext.tsx var AutumnContext = (0, import_react.createContext)({ customerProvider: null, pricingTableProvider: { pricingTableProducts: null, isLoading: true, error: null, refetch: () => Promise.resolve() }, entityProvider: { entity: null, isLoading: true, error: null, refetch: () => Promise.resolve(), lastParams: null }, client: new AutumnClient({ backendUrl: "http://localhost:8000" }), paywallDialog: { props: null, setProps: () => { }, open: false, setOpen: () => { }, setComponent: () => { } }, prodChangeDialog: { props: null, setProps: () => { }, open: false, setOpen: () => { }, setComponent: () => { } } }); var useAutumnContext = () => { const context = (0, import_react.useContext)(AutumnContext); if (context === void 0) { throw new Error( "useAutumnContext must be used within a AutumnContextProvider" ); } return context; }; // src/libraries/react/BaseAutumnProvider.tsx var import_react6 = require("react"); // src/libraries/react/hooks/useDialog.tsx var import_react2 = require("react"); var useDialog = (component) => { const [dialogProps, setDialogProps] = (0, import_react2.useState)(null); const [dialogOpen, setDialogOpen] = (0, import_react2.useState)(false); (0, import_react2.useEffect)(() => { if (!dialogOpen) { setTimeout(() => { setDialogProps(null); }, 200); } }, [dialogOpen]); return [dialogProps, setDialogProps, dialogOpen, setDialogOpen]; }; // src/libraries/react/hooks/usePricingTableProvider.tsx var import_react3 = require("react"); var usePricingTableProvider = ({ client }) => { const [pricingTableProducts, setPricingTableProducts] = (0, import_react3.useState)(null); const [isLoading, setIsLoading] = (0, import_react3.useState)(true); const [error, setError] = (0, import_react3.useState)(null); const fetchProducts = async () => { try { setIsLoading(true); const { data, error: error2 } = await client.getPricingTable(); if (error2) { setError(error2); setPricingTableProducts(null); } else { setPricingTableProducts(data?.list || []); setError(null); } } catch (error2) { setError( new AutumnError({ message: "Failed to fetch pricing table products", code: "failed_to_fetch_pricing_table_products" }) ); setPricingTableProducts(null); } finally { setIsLoading(false); } }; return { pricingTableProducts, isLoading: isLoading && !pricingTableProducts, error, refetch: fetchProducts }; }; // src/libraries/react/hooks/useEntityProvider.tsx var import_react4 = require("react"); var useEntityProvider = ({ client }) => { const [entity, setEntity] = (0, import_react4.useState)(null); const [error, setError] = (0, import_react4.useState)(null); const [isLoading, setIsLoading] = (0, import_react4.useState)(true); const [lastParams, setLastParams] = (0, import_react4.useState)(null); const fetchEntity = async ({ entityId, params }) => { if (!entityId) { console.warn("(Autumn) No entity ID provided in useEntity hook"); return; } setIsLoading(true); setLastParams(params || null); try { const { data, error: error2 } = await client.entities.get(entityId, params); if (error2) { setError(error2); setEntity(null); } else { setEntity(data); setError(null); } } catch (error2) { setError( new AutumnError({ message: error2?.message || "Failed to fetch entity", code: "entity_fetch_failed" }) ); } setIsLoading(false); }; return { entity, isLoading, error, refetch: fetchEntity, lastParams }; }; // src/libraries/react/hooks/useCustomerProvider.tsx var import_react5 = require("react"); function useCustomerProvider(client) { const [stateMap, setStateMap] = (0, import_react5.useState)({}); const inProgressFetches = (0, import_react5.useRef)({}); const getQueryKey = (params) => { return JSON.stringify(params || {}); }; const getState = (params) => { const queryKey = getQueryKey(params); if (!stateMap[queryKey]) { return { customer: null, isLoading: true, error: null }; } return stateMap[queryKey]; }; const refetch = async ({ params, errorOnNotFound = true }) => { const queryKey = getQueryKey(params); if (inProgressFetches.current[queryKey]) { return; } inProgressFetches.current[queryKey] = true; setStateMap((prevState) => ({ ...prevState, [queryKey]: { ...prevState[queryKey] || { customer: null }, isLoading: true, error: null } })); const { data, error } = await client.createCustomer({ expand: params?.expand, errorOnNotFound }); let newState = { customer: data, isLoading: false, error }; setStateMap((prevState) => ({ ...prevState, [queryKey]: newState })); inProgressFetches.current[queryKey] = false; }; const refetchFirstTwo = async () => { try { let batchRefetch = []; for (const key of Object.keys(stateMap)) { batchRefetch.push(refetch({ params: JSON.parse(key) })); } await Promise.all(batchRefetch); } catch (error) { console.error("Failed to refetch customer (useCustomerProvider)"); console.error(error); } }; return { // stateMap, getState, refetch, refetchFirstTwo }; } // src/libraries/react/BaseAutumnProvider.tsx var import_jsx_runtime = require("react/jsx-runtime"); function BaseAutumnProvider({ client, children }) { const [components, setComponents] = (0, import_react6.useState)({}); const [paywallProps, setPaywallProps, paywallOpen, setPaywallOpen] = useDialog(components.paywallDialog); const [ productChangeProps, setProductChangeProps, productChangeOpen, setProductChangeOpen ] = useDialog(components.productChangeDialog); const customerProvider = useCustomerProvider(client); const entityProvider = useEntityProvider({ client }); const { pricingTableProducts, isLoading: pricingTableLoading, error: pricingTableError, refetch } = usePricingTableProvider({ client }); (0, import_react6.useEffect)(() => { customerProvider.refetch({ errorOnNotFound: false }); }, []); return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( AutumnContext.Provider, { value: { customerProvider, entityProvider, pricingTableProvider: { pricingTableProducts, isLoading: pricingTableLoading, error: pricingTableError, refetch }, client, paywallDialog: { props: paywallProps, setProps: setPaywallProps, open: paywallOpen, setOpen: setPaywallOpen, setComponent: (component) => { setComponents({ ...components, paywallDialog: component }); } }, prodChangeDialog: { props: productChangeProps, setProps: setProductChangeProps, open: productChangeOpen, setOpen: setProductChangeOpen, setComponent: (component) => { setComponents({ ...components, productChangeDialog: component }); } } }, children: [ components.paywallDialog && /* @__PURE__ */ (0, import_jsx_runtime.jsx)( components.paywallDialog, { open: paywallOpen, setOpen: setPaywallOpen, ...paywallProps } ), components.productChangeDialog && /* @__PURE__ */ (0, import_jsx_runtime.jsx)( components.productChangeDialog, { open: productChangeOpen, setOpen: setProductChangeOpen, ...productChangeProps } ), children ] } ); } // src/libraries/react/ReactAutumnProvider.tsx var import_jsx_runtime2 = require("react/jsx-runtime"); var ReactAutumnProvider = ({ children, getBearerToken, backendUrl, customerData, includeCredentials = true }) => { let client = new AutumnClient({ backendUrl, getBearerToken, customerData, includeCredentials }); return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BaseAutumnProvider, { client, children }); }; // src/libraries/react/hooks/useCustomer.tsx var import_react7 = require("react"); var useCustomer = (params) => { const { customerProvider, client } = useAutumnContext(); const { getState, refetch } = customerProvider; const { customer, isLoading, error } = getState(params); (0, import_react7.useEffect)(() => { if (!customer) { refetch({ params }); } }, []); return { customer, isLoading: isLoading && !customer, error, refetch: async () => { await refetch({ params }); }, createEntity: client.entities.create, createReferralCode: client.referrals.createCode, redeemReferralCode: client.referrals.redeemCode }; }; // src/libraries/react/hooks/useAutumn.tsx var useAutumn = () => { const { client } = useAutumnContext(); const { prodChangeDialog, paywallDialog, pricingTableProvider, customerProvider } = useAutumnContext(); let { setProps: setProdChangeDialogProps, setOpen: setProdChangeDialogOpen, setComponent: setProdChangeComponent } = prodChangeDialog; let { setProps: setPaywallDialogProps, setOpen: setPaywallDialogOpen, setComponent: setPaywallComponent } = paywallDialog; const attachWithDialog = async (params) => { const attachWithoutDialog = async (options) => { let { dialog, ...rest } = params; return await attach(rest); }; const { productId, entityId, entityData } = params; const checkRes = await client.check({ productId, entityId, entityData, withPreview: "formatted" }); if (checkRes.error) { return checkRes; } let preview = checkRes.data.preview; if (!preview) { return await attachWithoutDialog(); } else { setProdChangeDialogProps({ preview }); setProdChangeDialogOpen(true); } return checkRes; }; const attach = async (params) => { const { dialog, callback, openInNewTab } = params; if (dialog) { setProdChangeComponent(dialog); return await attachWithDialog(params); } const result = await client.attach(params); if (result.error) { return result; } let data = result.data; if (data?.checkout_url && typeof window !== "undefined") { if (openInNewTab) { window.open(data.checkout_url, "_blank"); } else { window.location.href = data.checkout_url; } } try { await callback?.(); } catch (error) { return result; } await Promise.all([ pricingTableProvider.pricingTableProducts ? pricingTableProvider.refetch().catch((error) => { console.warn("Failed to refetch pricing table data"); console.warn(error); }) : Promise.resolve(), customerProvider.refetchFirstTwo() ]); if (setProdChangeDialogOpen) { setProdChangeDialogOpen(false); } return result; }; const cancel = async (params) => { const res = await client.cancel(params); if (res.error) { return res; } return res; }; const check = async (params) => { let { dialog, withPreview } = params; if (dialog) { setPaywallComponent(dialog); } const res = await client.check({ ...params, withPreview: withPreview || dialog ? "formatted" : void 0 }); if (res.error) { return res; } let data = res.data; if (data && data.preview && dialog) { let preview = data.preview; setPaywallDialogProps({ preview }); setPaywallDialogOpen(true); } return res; }; const track = async (params) => { const res = await client.track(params); if (res.error) { return res; } return res; }; const openBillingPortal = async (params) => { const res = await client.openBillingPortal(params); if (res.error) { return res; } let data = res.data; if (data?.url && typeof window !== "undefined") { window.open(data.url, "_blank"); return res; } else { return res; } }; return { attach, check, track, cancel, openBillingPortal }; }; // src/libraries/react/hooks/usePricingTable.tsx var import_react8 = require("react"); var mergeProductDetails = (products, productDetails) => { if (!products) { return null; } if (!productDetails) { return products; } let mergedProducts = structuredClone(products); for (const product of productDetails) { let index = mergedProducts.findIndex((p) => p.id === product.id); if (index == -1) { console.warn(`Product with id ${product.id} not found`); continue; } mergedProducts[index] = { ...mergedProducts[index], ...product }; } return mergedProducts; }; var usePricingTable = (options) => { const { pricingTableProvider } = useAutumnContext(); const { pricingTableProducts, isLoading, error, refetch } = pricingTableProvider; (0, import_react8.useEffect)(() => { if (!pricingTableProducts) { refetch(); } }, [pricingTableProducts]); return { products: mergeProductDetails( pricingTableProducts || void 0, options?.productDetails ), isLoading: isLoading && !pricingTableProducts, error, refetch }; }; // src/libraries/react/hooks/useEntity.tsx var import_react9 = require("react"); // src/libraries/react/utils/compareParams.ts var compareParams = (a, b) => { if (a === b) return true; if (a === null || b === null) return false; if (typeof a !== "object" || typeof b !== "object") return false; if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) return false; return a.every((item, index) => compareParams(item, b[index])); } const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; return keysA.every((key) => { if (!Object.prototype.hasOwnProperty.call(b, key)) return false; return compareParams(a[key], b[key]); }); }; // src/libraries/react/hooks/useEntity.tsx var useEntity = (entityId, params) => { const { entityProvider } = useAutumnContext(); const { entity, isLoading, error, refetch: refetchEntity, lastParams } = entityProvider; (0, import_react9.useEffect)(() => { if (entityId !== entity?.id || !compareParams(params, lastParams)) { refetchEntity({ entityId, params }); } }, [entityId]); return { entity, isLoading: isLoading && !entity, error, refetch: async (params2) => { await refetchEntity({ entityId, params: params2 }); } }; }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { AutumnProvider, useAutumn, useCustomer, useEntity, usePricingTable });