UNPKG

autumn-js

Version:
482 lines (474 loc) 14.4 kB
import { getIdentityContext, getOrganizationContext, scopeContainsOrg } from "./chunk-SRJD6EXQ.mjs"; import { secretKeyCheck } from "./chunk-UNZHJTEY.mjs"; import { createRouterWithOptions } from "./chunk-OFKRGNWA.mjs"; import "./chunk-HGB236VV.mjs"; import "./chunk-ZGI3AYWD.mjs"; import "./chunk-S46FBNO3.mjs"; import "./chunk-NCJ2TKEX.mjs"; import "./chunk-TUGNGQW2.mjs"; import "./chunk-UJBSJTAV.mjs"; import { Autumn, CustomerExpandEnum, QueryRangeEnum } from "./chunk-UJN5NVTZ.mjs"; import "./chunk-SGEUXFOF.mjs"; import "./chunk-KSG3E4Q2.mjs"; // src/libraries/backend/better-auth.ts import { getSessionFromCtx } from "better-auth/api"; import { createAuthEndpoint } from "better-auth/plugins"; import { APIError, createEndpoint } from "better-call"; import { findRoute } from "rou3"; import { z as z6 } from "zod/v4"; // src/libraries/react/client/types/clientAnalyticsTypes.ts import { z } from "zod/v4"; var PagePaginationDefaults = { Limit: 100, MaxLimit: 1e3 }; var PagePaginationQuerySchema = z.object({ offset: z.coerce.number().int().min(0).default(0).optional().describe("Number of items to skip"), limit: z.coerce.number().int().min(1).max(PagePaginationDefaults.MaxLimit).optional().describe( `Number of items to return. Default ${PagePaginationDefaults.Limit}, max ${PagePaginationDefaults.MaxLimit}.` ) }); var EventsListParamsSchema = PagePaginationQuerySchema.extend({ featureId: z.string().min(1).or(z.array(z.string().min(1))).describe("Filter by specific feature ID(s)"), customRange: z.object({ start: z.coerce.number().optional().describe("Filter events after this timestamp (epoch milliseconds)"), end: z.coerce.number().optional().describe("Filter events before this timestamp (epoch milliseconds)") }).optional().describe("Filter events by time range") }); var RangeEnumSchema = z.enum([ "24h", "7d", "30d", "90d", "last_cycle", "1bc", "3bc" ]); var BinSizeEnumSchema = z.enum(["day", "hour"]).default("day"); var EventAggregationParamsSchema = z.object({ featureId: z.string().min(1).or(z.array(z.string().min(1))).describe("Feature ID(s) to aggregate"), groupBy: z.string().startsWith("properties.").optional().describe("Group results by a property field (e.g., 'properties.region')"), range: RangeEnumSchema.optional().describe( "Predefined time range. One of: 24h, 7d, 30d, 90d, last_cycle, 1bc, 3bc" ), binSize: BinSizeEnumSchema.describe( "Bin size for aggregation: 'day' or 'hour'" ).optional(), customRange: z.object({ start: z.number().describe("Start timestamp (epoch milliseconds)"), end: z.number().describe("End timestamp (epoch milliseconds)") }).optional().describe("Custom time range (mutually exclusive with range)") }); var EventAggregationTotalSchema = z.record( z.string(), z.object({ count: z.number(), sum: z.number() }) ); // src/libraries/react/client/types/clientAttachTypes.ts import { z as z2 } from "zod/v4"; var AttachFeatureOptionsSchema = z2.object({ featureId: z2.string(), quantity: z2.number() }); var AttachParamsSchema = z2.object({ productId: z2.string().optional(), entityId: z2.string().optional(), options: z2.array(AttachFeatureOptionsSchema).optional(), productIds: z2.array(z2.string()).optional(), freeTrial: z2.boolean().optional(), successUrl: z2.string().optional(), metadata: z2.record(z2.string(), z2.string()).optional(), forceCheckout: z2.boolean().optional(), /** * @deprecated This field is deprecated and will be removed in a future version. */ dialog: z2.any().optional().describe( "DEPRECATED: This field is deprecated and will be removed in a future version. Please use the checkout() method instead." ), entityData: z2.any().optional(), openInNewTab: z2.boolean().optional(), reward: z2.string().optional(), checkoutSessionParams: z2.record(z2.string(), z2.any()).optional(), newBillingSubscription: z2.boolean().optional() }); var CheckoutParamsSchema = z2.object({ productId: z2.string().optional(), productIds: z2.array(z2.string()).optional(), entityId: z2.string().optional(), entityData: z2.any().optional(), options: z2.array(AttachFeatureOptionsSchema).optional(), successUrl: z2.string().optional(), openInNewTab: z2.boolean().optional(), dialog: z2.any().optional(), forceCheckout: z2.boolean().optional(), freeTrial: z2.boolean().optional(), checkoutSessionParams: z2.record(z2.string(), z2.any()).optional(), reward: z2.string().optional(), newBillingSubscription: z2.boolean().optional() }); // src/libraries/react/client/types/clientEntTypes.ts import { z as z3 } from "zod/v4"; var CreateEntityParamsSchema = z3.object({ id: z3.string(), name: z3.string().optional(), featureId: z3.string() }); var GetEntityParamsSchema = z3.object({ expand: z3.array(z3.string()).optional() }); var EntityDataParamsSchema = z3.object({ name: z3.string().optional(), featureId: z3.string() }); // src/libraries/react/client/types/clientGenTypes.ts import { z as z4 } from "zod/v4"; var CancelParamsSchema = z4.object({ productId: z4.string(), entityId: z4.string().optional(), cancelImmediately: z4.boolean().optional() }); var CheckParamsSchema = z4.object({ featureId: z4.string().optional(), productId: z4.string().optional(), entityId: z4.string().optional(), requiredBalance: z4.number().optional(), sendEvent: z4.boolean().optional(), withPreview: z4.boolean().optional(), dialog: z4.any().optional(), entityData: z4.any().optional(), properties: z4.record(z4.string(), z4.any()).optional() }); var TrackParamsSchema = z4.object({ featureId: z4.string().optional(), eventName: z4.string().optional(), entityId: z4.string().optional(), value: z4.number().optional(), idempotencyKey: z4.string().optional(), entityData: z4.any().optional() }); var OpenBillingPortalParamsSchema = z4.object({ returnUrl: z4.string().optional(), openInNewTab: z4.boolean().optional() }); var SetupPaymentParamsSchema = z4.object({ successUrl: z4.string().optional(), checkoutSessionParams: z4.record(z4.string(), z4.any()).optional(), openInNewTab: z4.boolean().optional() }).optional(); var QueryParamsSchema = z4.object({ featureId: z4.string().or(z4.array(z4.string())), range: QueryRangeEnum.optional() }); // src/libraries/react/client/types/clientReferralTypes.ts import { z as z5 } from "zod/v4"; var CreateReferralCodeParamsSchema = z5.object({ programId: z5.string() }); var RedeemReferralCodeParamsSchema = z5.object({ code: z5.string() }); // src/libraries/backend/better-auth.ts var betterAuthPathMap = { // "create-customer": "customers", // "customers/get": "customers", checkout: "checkout", attach: "attach", check: "check", track: "track", cancel: "cancel", query: "query", "referrals/redeem-code": "referrals/redeem", "referrals/create-code": "referrals/code", "open-billing-portal": "billing_portal" // "products/list": "products", }; var handleReq = async ({ ctx, options, method }) => { const { found, error: resError } = secretKeyCheck(); if (!found && !options?.secretKey) { throw new APIError(resError?.statusCode ?? "BAD_REQUEST", { message: resError?.message ?? "Unknown error", code: resError?.code ?? "unknown_error" }); } const client = new Autumn({ url: options?.url, secretKey: options?.secretKey }); const router = createRouterWithOptions({ suppressLogs: options?.suppressLogs }); let searchParams = {}; try { const req = ctx.request; const url = new URL(req.url); searchParams = Object.fromEntries(url.searchParams); } catch (_) { } const rest = ctx.path.split("/autumn/")[1]; const pathname = `/api/autumn/${betterAuthPathMap[rest] || rest}`; const match = findRoute(router, method, pathname); if (!match) return ctx.json({ error: "Not found" }, { status: 404 }); const { data } = match; const { handler } = data; const body = ctx.body; const params = ctx.params; let identify; const orgContext = await getOrganizationContext(ctx, options); const finalSession = await getSessionFromCtx(ctx); let identity = null; if (options?.identify) { identity = await getIdentityContext({ orgContext, options, session: finalSession }); } if (options?.identify) { identify = () => identity; } else { identify = () => { if (!finalSession) return; if (scopeContainsOrg({ options })) { if (orgContext.activeOrganization?.id) { return { customerId: orgContext.activeOrganization?.id, customerData: { email: orgContext.activeOrganizationEmail, name: orgContext.activeOrganization?.name ?? "" } }; } else { if (options?.customerScope === "user_and_organization") { return { customerId: finalSession.user.id, customerData: { email: finalSession.user.email, name: finalSession.user.name } }; } else return null; } } else { return { customerId: finalSession.user.id, customerData: { email: finalSession.user.email, name: finalSession.user.name } }; } }; } const result = await handler({ autumn: client, body, path: pathname, getCustomer: identify, pathParams: params, searchParams }); if (result.statusCode >= 400) { throw new APIError(result.statusCode, { message: result.body.message ?? "Unknown error", code: result.body.code ?? "unknown_error" }); } return ctx.json(result.body, { status: result.statusCode }); }; var autumn = (options) => { return { id: "autumn", endpoints: { createCustomer: createEndpoint( "/autumn/customers", { method: "POST", use: [], body: z6.object({ errorOnNotFound: z6.boolean().optional(), expand: z6.array(CustomerExpandEnum).optional() }), metadata: { isAction: false } }, async (ctx) => await handleReq({ ctx, options, method: "POST" }) ), listProducts: createAuthEndpoint( "/autumn/products", { method: "GET", use: [] }, async (ctx) => await handleReq({ ctx, options, method: "GET" }) ), checkout: createAuthEndpoint( "/autumn/checkout", { method: "POST", use: [], body: CheckoutParamsSchema }, async (ctx) => { return await handleReq({ ctx, options, method: "POST" }); } ), attach: createAuthEndpoint( "/autumn/attach", { method: "POST", use: [], body: AttachParamsSchema }, async (ctx) => await handleReq({ ctx, options, method: "POST" }) ), check: createAuthEndpoint( "/autumn/check", { method: "POST", use: [], body: CheckParamsSchema }, async (ctx) => { return await handleReq({ ctx, options, method: "POST" }); } ), track: createAuthEndpoint( "/autumn/track", { method: "POST", use: [], body: TrackParamsSchema }, async (ctx) => { return await handleReq({ ctx, options, method: "POST" }); } ), cancel: createAuthEndpoint( "/autumn/cancel", { method: "POST", use: [], body: CancelParamsSchema }, async (ctx) => await handleReq({ ctx, options, method: "POST" }) ), query: createAuthEndpoint( "/autumn/query", { method: "POST", use: [], body: QueryParamsSchema }, async (ctx) => await handleReq({ ctx, options, method: "POST" }) ), createReferralCode: createAuthEndpoint( "/autumn/referrals/code", { method: "POST", use: [], body: CreateReferralCodeParamsSchema }, async (ctx) => { return await handleReq({ ctx, options, method: "POST" }); } ), redeemReferralCode: createAuthEndpoint( "/autumn/referrals/redeem", { method: "POST", use: [], body: RedeemReferralCodeParamsSchema }, async (ctx) => { return await handleReq({ ctx, options, method: "POST" }); } ), billingPortal: createAuthEndpoint( "/autumn/billing_portal", { method: "POST", use: [], body: OpenBillingPortalParamsSchema, metadata: { isAction: false } }, async (ctx) => { return await handleReq({ ctx, options, method: "POST" }); } ), createEntity: createAuthEndpoint( "/autumn/entities", { method: "POST", use: [], body: CreateEntityParamsSchema }, async (ctx) => { return await handleReq({ ctx, options, method: "POST" }); } ), getEntity: createAuthEndpoint( "/autumn/entities/:entityId", { method: "GET", use: [] }, async (ctx) => { return await handleReq({ ctx, options, method: "GET" }); } ), deleteEntity: createAuthEndpoint( "/autumn/entities/:entityId", { method: "DELETE", use: [] }, async (ctx) => await handleReq({ ctx, options, method: "DELETE" }) ), listEvents: createAuthEndpoint( "/autumn/events/list", { method: "POST", use: [], body: EventsListParamsSchema }, async (ctx) => await handleReq({ ctx, options, method: "POST" }) ), aggregateEvents: createAuthEndpoint( "/autumn/events/aggregate", { method: "POST", use: [], body: EventAggregationParamsSchema }, async (ctx) => await handleReq({ ctx, options, method: "POST" }) ) } }; }; export { autumn };