@commet/better-auth 1.0.0 → 1.0.1

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/hooks/customer.ts","../src/client.ts","../src/plugins/portal.ts","../src/plugins/subscriptions.ts","../src/plugins/features.ts","../src/plugins/usage.ts","../src/plugins/seats.ts","../src/plugins/webhooks.ts"],"sourcesContent":["import type { BetterAuthPlugin } from \"better-auth\";\nimport {\n onAfterUserCreate,\n onBeforeUserCreate,\n onUserDelete,\n onUserUpdate,\n} from \"./hooks/customer\";\nimport type { CommetEndpoints, CommetOptions } from \"./types\";\n\n// Re-export client plugin\nexport { commetClient } from \"./client\";\n\n// Re-export all plugins\nexport { portal } from \"./plugins/portal\";\nexport type { PortalConfig } from \"./plugins/portal\";\n\nexport { subscriptions } from \"./plugins/subscriptions\";\nexport type { SubscriptionsConfig } from \"./plugins/subscriptions\";\n\nexport { features } from \"./plugins/features\";\nexport type { FeaturesConfig } from \"./plugins/features\";\n\nexport { usage } from \"./plugins/usage\";\nexport type { UsageConfig } from \"./plugins/usage\";\n\nexport { seats } from \"./plugins/seats\";\nexport type { SeatsConfig } from \"./plugins/seats\";\n\nexport { webhooks } from \"./plugins/webhooks\";\nexport type { WebhooksConfig, WebhookHandler } from \"./plugins/webhooks\";\n\n// Re-export types\nexport type {\n CommetOptions,\n CommetPlugin,\n CommetPlugins,\n CommetEndpoints,\n CustomerCreateParams,\n PlanMapping,\n} from \"./types\";\n\n/**\n * Commet plugin for Better Auth\n *\n * Integrates Commet billing with Better Auth authentication.\n *\n * @example\n * ```typescript\n * import { betterAuth } from \"better-auth\";\n * import { commet, portal, subscriptions, features, usage, seats, webhooks } from \"@commet/better-auth\";\n * import { Commet } from \"@commet/node\";\n *\n * const commetClient = new Commet({\n * apiKey: process.env.COMMET_API_KEY,\n * environment: \"production\"\n * });\n *\n * const auth = betterAuth({\n * plugins: [\n * commet({\n * client: commetClient,\n * createCustomerOnSignUp: true,\n * getCustomerCreateParams: ({ user }) => ({\n * legalName: user.name,\n * metadata: { source: \"signup\" }\n * }),\n * use: [\n * portal({ returnUrl: \"/dashboard\" }),\n * subscriptions(),\n * features(),\n * usage(),\n * seats(),\n * // Webhooks are OPTIONAL - you can always query state directly\n * webhooks({\n * secret: process.env.COMMET_WEBHOOK_SECRET,\n * onSubscriptionActivated: async (payload) => { ... }\n * })\n * ]\n * })\n * ]\n * });\n * ```\n */\nexport const commet = <O extends CommetOptions>(options: O) => {\n // Compose all plugin endpoints\n const plugins = options.use\n .map((use) => use(options.client))\n .reduce((acc, plugin) => {\n Object.assign(acc, plugin);\n return acc;\n }, {} as CommetEndpoints);\n\n return {\n id: \"commet\",\n endpoints: {\n ...plugins,\n },\n init() {\n return {\n options: {\n databaseHooks: {\n user: {\n create: {\n before: onBeforeUserCreate(options),\n after: onAfterUserCreate(options),\n },\n update: {\n after: onUserUpdate(options),\n },\n delete: {\n after: onUserDelete(options),\n },\n },\n },\n },\n };\n },\n } satisfies BetterAuthPlugin;\n};\n\n","import type { GenericEndpointContext, User } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\nimport type { CommetOptions } from \"../types\";\n\n/**\n * Hook called before a user is created in Better Auth\n * Creates a Commet customer if createCustomerOnSignUp is enabled\n */\nexport const onBeforeUserCreate =\n (options: CommetOptions) =>\n async (user: Partial<User>, context: GenericEndpointContext | null) => {\n if (!context || !options.createCustomerOnSignUp) {\n return;\n }\n\n try {\n const customParams = options.getCustomerCreateParams\n ? await options.getCustomerCreateParams({ user }, context.request)\n : {};\n\n if (!user.email) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"An email is required to create a customer\",\n });\n }\n\n // Check if customer already exists by email\n const existingCustomers = await options.client.customers.list({\n search: user.email,\n });\n\n const existingCustomer = existingCustomers.data?.find(\n (c) => c.billingEmail === user.email,\n );\n\n // Skip creation if customer already exists\n if (!existingCustomer) {\n await options.client.customers.create({\n email: user.email,\n legalName: customParams.legalName ?? user.name,\n displayName: customParams.displayName,\n domain: customParams.domain,\n metadata: customParams.metadata,\n });\n }\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: `Commet customer creation failed: ${e.message}`,\n });\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Commet customer creation failed\",\n });\n }\n };\n\n/**\n * Hook called after a user is created in Better Auth\n * Updates the Commet customer with the externalId (Better Auth user ID)\n */\nexport const onAfterUserCreate =\n (options: CommetOptions) =>\n async (user: User, context: GenericEndpointContext | null) => {\n if (!context || !options.createCustomerOnSignUp) {\n return;\n }\n\n try {\n // Find customer by email and update with externalId\n const existingCustomers = await options.client.customers.list({\n search: user.email,\n });\n\n const existingCustomer = existingCustomers.data?.find(\n (c) => c.billingEmail === user.email,\n );\n\n if (existingCustomer && existingCustomer.externalId !== user.id) {\n await options.client.customers.update({\n customerId: existingCustomer.id,\n externalId: user.id,\n });\n }\n } catch (e: unknown) {\n if (e instanceof Error) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: `Commet customer update failed: ${e.message}`,\n });\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Commet customer update failed\",\n });\n }\n };\n\n/**\n * Hook called when a user is updated in Better Auth\n * Syncs email and name changes to the Commet customer\n */\nexport const onUserUpdate =\n (options: CommetOptions) =>\n async (user: User, context: GenericEndpointContext | null) => {\n if (!context || !options.createCustomerOnSignUp) {\n return;\n }\n\n try {\n // Find customer by externalId and update\n const existingCustomers = await options.client.customers.list({\n externalId: user.id,\n });\n\n const existingCustomer = existingCustomers.data?.[0];\n\n if (existingCustomer) {\n await options.client.customers.update({\n customerId: existingCustomer.id,\n email: user.email,\n legalName: user.name ?? undefined,\n });\n }\n } catch (e: unknown) {\n // Log but don't throw - update failures shouldn't break the auth flow\n if (e instanceof Error) {\n context.context.logger.error(\n `Commet customer update failed: ${e.message}`,\n );\n } else {\n context.context.logger.error(\"Commet customer update failed\");\n }\n }\n };\n\n/**\n * Hook called when a user is deleted in Better Auth\n * Archives the corresponding Commet customer\n */\nexport const onUserDelete =\n (options: CommetOptions) =>\n async (user: User, context: GenericEndpointContext | null) => {\n if (!context || !options.createCustomerOnSignUp) {\n return;\n }\n\n try {\n // Find customer by externalId and archive\n const existingCustomers = await options.client.customers.list({\n externalId: user.id,\n });\n\n const existingCustomer = existingCustomers.data?.[0];\n\n if (existingCustomer) {\n await options.client.customers.archive(existingCustomer.id);\n }\n } catch (e: unknown) {\n // Log but don't throw - archive failures shouldn't break the auth flow\n if (e instanceof Error) {\n context?.context.logger.error(\n `Commet customer archive failed: ${e.message}`,\n );\n } else {\n context?.context.logger.error(\"Commet customer archive failed\");\n }\n }\n };\n","import type { BetterAuthClientPlugin } from \"better-auth\";\nimport type { BetterFetchOption } from \"better-auth/client\";\nimport type { commet } from \"./index\";\n\n/**\n * Commet client plugin for Better Auth\n *\n * Provides client-side methods to interact with Commet billing features.\n *\n * @example\n * ```typescript\n * import { createAuthClient } from \"better-auth/react\";\n * import { commetClient } from \"@commet/better-auth\";\n *\n * export const authClient = createAuthClient({\n * plugins: [commetClient()]\n * });\n *\n * // Usage - you can always query state directly (no webhooks needed)\n * const { data: subscription } = await authClient.subscription.get();\n * const { data: features } = await authClient.features.list();\n * const { data: canUse } = await authClient.features.canUse({ code: \"api_calls\" });\n * await authClient.usage.track({ eventType: \"api_call\" });\n * await authClient.customer.portal(); // Redirect to portal\n * ```\n */\nexport const commetClient = () => {\n return {\n id: \"commet-client\",\n $InferServerPlugin: {} as ReturnType<typeof commet>,\n getActions: ($fetch) => {\n return {\n // Customer Portal\n customer: {\n /**\n * Redirect to the Commet customer portal\n */\n portal: async (fetchOptions?: BetterFetchOption) => {\n const res = await $fetch(\"/commet/portal\", {\n method: \"GET\",\n ...fetchOptions,\n });\n\n if (res.error) {\n throw new Error(res.error.message);\n }\n\n const data = res.data as { url: string; redirect: boolean };\n\n if (data.redirect && typeof window !== \"undefined\") {\n window.location.href = data.url;\n }\n\n return data;\n },\n },\n\n // Subscription management\n subscription: {\n /**\n * Get the current subscription for the authenticated user\n */\n get: async (fetchOptions?: BetterFetchOption) => {\n return $fetch(\"/commet/subscription\", {\n method: \"GET\",\n ...fetchOptions,\n });\n },\n\n /**\n * Change the subscription plan (upgrade/downgrade)\n */\n changePlan: async (\n data: {\n planId?: string;\n slug?: string;\n billingInterval?: \"monthly\" | \"quarterly\" | \"yearly\";\n },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/subscription/change-plan\", {\n method: \"POST\",\n body: data,\n ...fetchOptions,\n });\n },\n\n /**\n * Cancel the subscription\n */\n cancel: async (\n data?: { reason?: string; immediate?: boolean },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/subscription/cancel\", {\n method: \"POST\",\n body: data ?? {},\n ...fetchOptions,\n });\n },\n },\n\n // Feature access\n features: {\n /**\n * List all features for the authenticated user\n */\n list: async (fetchOptions?: BetterFetchOption) => {\n return $fetch(\"/commet/features\", {\n method: \"GET\",\n ...fetchOptions,\n });\n },\n\n /**\n * Get a specific feature's access/usage\n */\n get: async (\n data: { code: string },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(`/commet/features/${data.code}`, {\n method: \"GET\",\n ...fetchOptions,\n });\n },\n\n /**\n * Check if a feature is enabled (boolean check)\n */\n check: async (\n data: { code: string },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(`/features/${data.code}/check`, {\n method: \"GET\",\n ...fetchOptions,\n });\n },\n\n /**\n * Check if user can use one more unit of a feature\n * Returns { allowed: boolean, willBeCharged: boolean }\n */\n canUse: async (\n data: { code: string },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(`/features/${data.code}/can-use`, {\n method: \"GET\",\n ...fetchOptions,\n });\n },\n },\n\n // Usage tracking\n usage: {\n /**\n * Track a usage event for the authenticated user\n */\n track: async (\n data: {\n eventType: string;\n value?: number;\n idempotencyKey?: string;\n properties?: Record<string, string>;\n },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/usage/track\", {\n method: \"POST\",\n body: data,\n ...fetchOptions,\n });\n },\n },\n\n // Seat management\n seats: {\n /**\n * List all seat balances for the authenticated user\n */\n list: async (fetchOptions?: BetterFetchOption) => {\n return $fetch(\"/commet/seats\", {\n method: \"GET\",\n ...fetchOptions,\n });\n },\n\n /**\n * Add seats of a specific type\n */\n add: async (\n data: { seatType: string; count: number },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/seats/add\", {\n method: \"POST\",\n body: data,\n ...fetchOptions,\n });\n },\n\n /**\n * Remove seats of a specific type\n */\n remove: async (\n data: { seatType: string; count: number },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/seats/remove\", {\n method: \"POST\",\n body: data,\n ...fetchOptions,\n });\n },\n\n /**\n * Set seats to a specific count\n */\n set: async (\n data: { seatType: string; count: number },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/seats/set\", {\n method: \"POST\",\n body: data,\n ...fetchOptions,\n });\n },\n\n /**\n * Set all seat types at once\n */\n setAll: async (\n data: { seats: Record<string, number> },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/seats/set-all\", {\n method: \"POST\",\n body: data,\n ...fetchOptions,\n });\n },\n },\n };\n },\n } satisfies BetterAuthClientPlugin;\n};\n\n","import type { Commet } from \"@commet/node\";\nimport { APIError, sessionMiddleware } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/plugins\";\n\nexport interface PortalConfig {\n /**\n * URL to return to after leaving the customer portal\n */\n returnUrl?: string;\n}\n\n/**\n * Portal plugin - Provides customer portal access\n *\n * Endpoints:\n * - GET /customer/portal - Redirects to the Commet customer portal\n */\nexport const portal =\n ({ returnUrl }: PortalConfig = {}) =>\n (commet: Commet) => {\n return {\n portal: createAuthEndpoint(\n \"/commet/portal\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to access the customer portal\",\n });\n }\n\n try {\n const portalAccess = await commet.portal.getUrl({\n externalId: userId,\n });\n\n if (!portalAccess.success || !portalAccess.data) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message:\n portalAccess.message || \"Failed to generate portal URL\",\n });\n }\n\n // Append return URL if configured\n let portalUrl = portalAccess.data.portalUrl;\n if (returnUrl) {\n const url = new URL(portalUrl);\n url.searchParams.set(\"return_url\", returnUrl);\n portalUrl = url.toString();\n }\n\n return ctx.json({\n url: portalUrl,\n redirect: true,\n });\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet portal access failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to access customer portal\",\n });\n }\n },\n ),\n };\n };\n\n","import type { Commet } from \"@commet/node\";\nimport { APIError, sessionMiddleware } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/plugins\";\nimport { z } from \"zod\";\n\nexport interface SubscriptionsConfig {\n /**\n * Optional plan mappings for easy slug-based plan changes\n */\n plans?: Array<{ planId: string; slug: string }>;\n}\n\nconst ChangePlanSchema = z.object({\n planId: z.string().optional(),\n slug: z.string().optional(),\n billingInterval: z.enum([\"monthly\", \"quarterly\", \"yearly\"]).optional(),\n});\n\nconst CancelSchema = z.object({\n reason: z.string().optional(),\n immediate: z.boolean().optional(),\n});\n\n/**\n * Subscriptions plugin - Manage customer subscriptions\n *\n * Endpoints:\n * - GET /subscription - Get active subscription for the authenticated user\n * - POST /subscription/change-plan - Change subscription plan (upgrade/downgrade)\n * - POST /subscription/cancel - Cancel the subscription\n */\nexport const subscriptions =\n (config: SubscriptionsConfig = {}) =>\n (commet: Commet) => {\n return {\n getSubscription: createAuthEndpoint(\n \"/commet/subscription\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to view subscription\",\n });\n }\n\n try {\n const subscription = await commet.subscriptions.get(userId);\n\n if (!subscription.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message:\n subscription.message || \"Failed to retrieve subscription\",\n });\n }\n\n return ctx.json(subscription.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet subscription get failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to retrieve subscription\",\n });\n }\n },\n ),\n\n changePlan: createAuthEndpoint(\n \"/commet/subscription/change-plan\",\n {\n method: \"POST\",\n body: ChangePlanSchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to change plan\",\n });\n }\n\n // Resolve plan ID from slug if provided\n let planId = ctx.body.planId;\n if (ctx.body.slug && !planId) {\n const plan = config.plans?.find((p) => p.slug === ctx.body.slug);\n if (!plan) {\n throw new APIError(\"BAD_REQUEST\", {\n message: `Plan with slug \"${ctx.body.slug}\" not found`,\n });\n }\n planId = plan.planId;\n }\n\n if (!planId) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Either planId or slug must be provided\",\n });\n }\n\n try {\n // First get the current subscription\n const currentSub = await commet.subscriptions.get(userId);\n\n if (!currentSub.success || !currentSub.data) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"No active subscription found\",\n });\n }\n\n const result = await commet.subscriptions.changePlan({\n subscriptionId: currentSub.data.id,\n planId,\n billingInterval: ctx.body.billingInterval,\n });\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to change plan\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet plan change failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to change plan\",\n });\n }\n },\n ),\n\n cancelSubscription: createAuthEndpoint(\n \"/commet/subscription/cancel\",\n {\n method: \"POST\",\n body: CancelSchema.optional(),\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to cancel subscription\",\n });\n }\n\n try {\n // First get the current subscription\n const currentSub = await commet.subscriptions.get(userId);\n\n if (!currentSub.success || !currentSub.data) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"No active subscription found\",\n });\n }\n\n const result = await commet.subscriptions.cancel({\n subscriptionId: currentSub.data.id,\n reason: ctx.body?.reason,\n immediate: ctx.body?.immediate,\n });\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to cancel subscription\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet subscription cancel failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to cancel subscription\",\n });\n }\n },\n ),\n };\n };\n","import type { Commet } from \"@commet/node\";\nimport { APIError, sessionMiddleware } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/plugins\";\n\nexport interface FeaturesConfig {\n // Reserved for future configuration options\n}\n\n/**\n * Features plugin - Check feature access and usage\n *\n * Endpoints:\n * - GET /features - List all features for the authenticated user\n * - GET /features/:code - Get a specific feature's access/usage\n * - GET /features/:code/check - Check if feature is enabled (boolean check)\n * - GET /features/:code/can-use - Check if user can use one more unit\n */\nexport const features =\n (_config: FeaturesConfig = {}) =>\n (commet: Commet) => {\n return {\n listFeatures: createAuthEndpoint(\n \"/commet/features\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to view features\",\n });\n }\n\n try {\n const result = await commet.features.list(userId);\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to list features\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet features list failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to list features\",\n });\n }\n },\n ),\n\n getFeature: createAuthEndpoint(\n \"/commet/features/:code\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n const code = ctx.params?.code;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to view feature\",\n });\n }\n\n if (!code) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Feature code is required\",\n });\n }\n\n try {\n const result = await commet.features.get({\n externalId: userId,\n code,\n });\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to get feature\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet feature get failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to get feature\",\n });\n }\n },\n ),\n\n checkFeature: createAuthEndpoint(\n \"/commet/features/:code/check\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n const code = ctx.params?.code;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to check feature\",\n });\n }\n\n if (!code) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Feature code is required\",\n });\n }\n\n try {\n const result = await commet.features.check({\n externalId: userId,\n code,\n });\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to check feature\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet feature check failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to check feature\",\n });\n }\n },\n ),\n\n canUseFeature: createAuthEndpoint(\n \"/commet/features/:code/can-use\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n const code = ctx.params?.code;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to check feature usage\",\n });\n }\n\n if (!code) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Feature code is required\",\n });\n }\n\n try {\n const result = await commet.features.canUse({\n externalId: userId,\n code,\n });\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to check feature usage\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet feature canUse failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to check feature usage\",\n });\n }\n },\n ),\n };\n };\n","import type { Commet } from \"@commet/node\";\nimport { APIError, sessionMiddleware } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/plugins\";\nimport { z } from \"zod\";\n\nexport interface UsageConfig {\n // Reserved for future configuration options\n}\n\nconst TrackEventSchema = z.object({\n eventType: z.string(),\n value: z.number().optional(),\n idempotencyKey: z.string().optional(),\n properties: z.record(z.string(), z.string()).optional(),\n});\n\n/**\n * Usage plugin - Track usage events for metered billing\n *\n * Endpoints:\n * - POST /usage/track - Track a usage event for the authenticated user\n */\nexport const usage =\n (_config: UsageConfig = {}) =>\n (commet: Commet) => {\n return {\n trackUsage: createAuthEndpoint(\n \"/commet/usage/track\",\n {\n method: \"POST\",\n body: TrackEventSchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to track usage\",\n });\n }\n\n try {\n const result = await commet.usage.track(\n {\n externalId: userId,\n eventType: ctx.body.eventType,\n idempotencyKey: ctx.body.idempotencyKey,\n properties: ctx.body.properties,\n },\n {},\n );\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to track usage\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet usage track failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to track usage\",\n });\n }\n },\n ),\n };\n };\n","import type { Commet } from \"@commet/node\";\nimport { APIError, sessionMiddleware } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/plugins\";\nimport { z } from \"zod\";\n\nexport interface SeatsConfig {\n // Reserved for future configuration options\n}\n\nconst SeatOperationSchema = z.object({\n seatType: z.string(),\n count: z.number().min(1),\n});\n\nconst SetAllSeatsSchema = z.object({\n seats: z.record(z.string(), z.number()),\n});\n\n/**\n * Seats plugin - Manage seat-based licensing\n *\n * Endpoints:\n * - GET /seats - List all seat balances for the authenticated user\n * - POST /seats/add - Add seats of a specific type\n * - POST /seats/remove - Remove seats of a specific type\n * - POST /seats/set - Set seats to a specific count\n * - POST /seats/set-all - Set all seat types at once\n */\nexport const seats =\n (_config: SeatsConfig = {}) =>\n (commet: Commet) => {\n return {\n listSeats: createAuthEndpoint(\n \"/commet/seats\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to view seats\",\n });\n }\n\n try {\n const result = await commet.seats.getAllBalances({\n externalId: userId,\n });\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to list seats\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet seats list failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to list seats\",\n });\n }\n },\n ),\n\n addSeats: createAuthEndpoint(\n \"/commet/seats/add\",\n {\n method: \"POST\",\n body: SeatOperationSchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to add seats\",\n });\n }\n\n try {\n const result = await commet.seats.add(\n {\n externalId: userId,\n seatType: ctx.body.seatType,\n count: ctx.body.count,\n },\n {},\n );\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to add seats\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(`Commet seats add failed: ${e.message}`);\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to add seats\",\n });\n }\n },\n ),\n\n removeSeats: createAuthEndpoint(\n \"/commet/seats/remove\",\n {\n method: \"POST\",\n body: SeatOperationSchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to remove seats\",\n });\n }\n\n try {\n const result = await commet.seats.remove(\n {\n externalId: userId,\n seatType: ctx.body.seatType,\n count: ctx.body.count,\n },\n {},\n );\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to remove seats\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet seats remove failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to remove seats\",\n });\n }\n },\n ),\n\n setSeats: createAuthEndpoint(\n \"/commet/seats/set\",\n {\n method: \"POST\",\n body: SeatOperationSchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to set seats\",\n });\n }\n\n try {\n const result = await commet.seats.set(\n {\n externalId: userId,\n seatType: ctx.body.seatType,\n count: ctx.body.count,\n },\n {},\n );\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to set seats\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(`Commet seats set failed: ${e.message}`);\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to set seats\",\n });\n }\n },\n ),\n\n setAllSeats: createAuthEndpoint(\n \"/commet/seats/set-all\",\n {\n method: \"POST\",\n body: SetAllSeatsSchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to set seats\",\n });\n }\n\n try {\n const result = await commet.seats.setAll(\n {\n externalId: userId,\n seats: ctx.body.seats,\n },\n {},\n );\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to set all seats\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet seats set-all failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to set all seats\",\n });\n }\n },\n ),\n };\n };\n","import type { Commet, WebhookPayload, WebhookEvent } from \"@commet/node\";\nimport { APIError, createAuthEndpoint } from \"better-auth/api\";\n\n/**\n * Webhook handler function type\n */\nexport type WebhookHandler<T = WebhookPayload> = (payload: T) => Promise<void>;\n\n/**\n * Webhooks plugin configuration\n *\n * Note: Webhooks are OPTIONAL in Commet. You can always query the current state\n * using subscriptions.get(), features.list(), etc. Webhooks are useful if you want\n * to react immediately to events without polling.\n */\nexport interface WebhooksConfig {\n /**\n * Webhook secret for signature verification\n */\n secret: string;\n /**\n * Handler for subscription.created events\n */\n onSubscriptionCreated?: WebhookHandler;\n /**\n * Handler for subscription.activated events\n */\n onSubscriptionActivated?: WebhookHandler;\n /**\n * Handler for subscription.canceled events\n */\n onSubscriptionCanceled?: WebhookHandler;\n /**\n * Handler for subscription.updated events\n */\n onSubscriptionUpdated?: WebhookHandler;\n /**\n * Generic handler for all webhook events (catch-all)\n */\n onPayload?: WebhookHandler;\n}\n\n/**\n * Map event types to their handler keys\n */\nconst EVENT_HANDLER_MAP: Record<WebhookEvent, keyof WebhooksConfig> = {\n \"subscription.created\": \"onSubscriptionCreated\",\n \"subscription.activated\": \"onSubscriptionActivated\",\n \"subscription.canceled\": \"onSubscriptionCanceled\",\n \"subscription.updated\": \"onSubscriptionUpdated\",\n};\n\n/**\n * Webhooks plugin - Handle incoming Commet webhooks (OPTIONAL)\n *\n * You can always query the current state directly:\n * - authClient.subscription.get() for subscription status\n * - authClient.features.list() for feature access\n * - authClient.features.canUse() for usage checks\n *\n * Webhooks are useful when you want to:\n * - React immediately to changes (e.g., send email on cancellation)\n * - Avoid polling latency in critical cases\n * - Audit/log events\n *\n * Endpoint:\n * - POST /commet/webhooks - Receive and process Commet webhooks\n */\nexport const webhooks = (config: WebhooksConfig) => (commet: Commet) => {\n return {\n commetWebhooks: createAuthEndpoint(\n \"/commet/webhooks\",\n {\n method: \"POST\",\n metadata: {\n isAction: false,\n },\n cloneRequest: true,\n },\n async (ctx) => {\n if (!ctx.request?.body) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Request body is required\",\n });\n }\n\n const rawBody = await ctx.request.text();\n const signature = ctx.request.headers.get(\"x-commet-signature\");\n\n // Verify webhook signature\n const payload = commet.webhooks.verifyAndParse({\n rawBody,\n signature,\n secret: config.secret,\n });\n\n if (!payload) {\n ctx.context.logger.error(\"Invalid webhook signature\");\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"Invalid webhook signature\",\n });\n }\n\n try {\n // Call specific event handler if configured\n const handlerKey = EVENT_HANDLER_MAP[payload.event];\n if (handlerKey) {\n const handler = config[handlerKey] as WebhookHandler | undefined;\n if (handler) {\n await handler(payload);\n }\n }\n\n // Always call onPayload if configured (catch-all)\n if (config.onPayload) {\n await config.onPayload(payload);\n }\n\n return ctx.json({ received: true });\n } catch (e: unknown) {\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet webhook handler error: ${e.message}`,\n );\n } else {\n ctx.context.logger.error(\"Commet webhook handler error\");\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Webhook handler error\",\n });\n }\n },\n ),\n };\n};\n"],"mappings":"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","names":["import_api","commet","import_api","import_plugins","commet","import_api","import_plugins","commet","import_api","import_plugins","import_zod","commet","import_api","import_plugins","import_zod","commet","import_api","commet"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/hooks/customer.ts","../src/client.ts","../src/plugins/portal.ts","../src/plugins/subscriptions.ts","../src/plugins/features.ts","../src/plugins/usage.ts","../src/plugins/seats.ts","../src/plugins/webhooks.ts"],"sourcesContent":["import type { BetterAuthPlugin } from \"better-auth\";\nimport {\n onAfterUserCreate,\n onBeforeUserCreate,\n onUserDelete,\n onUserUpdate,\n} from \"./hooks/customer\";\nimport type { CommetEndpoints, CommetOptions } from \"./types\";\n\n// Re-export client plugin\nexport { commetClient } from \"./client\";\n\n// Re-export all plugins\nexport { portal } from \"./plugins/portal\";\nexport type { PortalConfig } from \"./plugins/portal\";\n\nexport { subscriptions } from \"./plugins/subscriptions\";\nexport type { SubscriptionsConfig } from \"./plugins/subscriptions\";\n\nexport { features } from \"./plugins/features\";\nexport type { FeaturesConfig } from \"./plugins/features\";\n\nexport { usage } from \"./plugins/usage\";\nexport type { UsageConfig } from \"./plugins/usage\";\n\nexport { seats } from \"./plugins/seats\";\nexport type { SeatsConfig } from \"./plugins/seats\";\n\nexport { webhooks } from \"./plugins/webhooks\";\nexport type { WebhooksConfig, WebhookHandler } from \"./plugins/webhooks\";\n\n// Re-export types\nexport type {\n CommetOptions,\n CommetPlugin,\n CommetPlugins,\n CommetEndpoints,\n CustomerCreateParams,\n PlanMapping,\n} from \"./types\";\n\n/**\n * Commet plugin for Better Auth\n *\n * Integrates Commet billing with Better Auth authentication.\n *\n * @example\n * ```typescript\n * import { betterAuth } from \"better-auth\";\n * import { commet, portal, subscriptions, features, usage, seats, webhooks } from \"@commet/better-auth\";\n * import { Commet } from \"@commet/node\";\n *\n * const commetClient = new Commet({\n * apiKey: process.env.COMMET_API_KEY,\n * environment: \"production\"\n * });\n *\n * const auth = betterAuth({\n * plugins: [\n * commet({\n * client: commetClient,\n * createCustomerOnSignUp: true,\n * getCustomerCreateParams: ({ user }) => ({\n * legalName: user.name,\n * metadata: { source: \"signup\" }\n * }),\n * use: [\n * portal({ returnUrl: \"/dashboard\" }),\n * subscriptions(),\n * features(),\n * usage(),\n * seats(),\n * // Webhooks are OPTIONAL - you can always query state directly\n * webhooks({\n * secret: process.env.COMMET_WEBHOOK_SECRET,\n * onSubscriptionActivated: async (payload) => { ... }\n * })\n * ]\n * })\n * ]\n * });\n * ```\n */\nexport const commet = <O extends CommetOptions>(options: O) => {\n // Compose all plugin endpoints\n const plugins = options.use\n .map((use) => use(options.client))\n .reduce((acc, plugin) => {\n Object.assign(acc, plugin);\n return acc;\n }, {} as CommetEndpoints);\n\n return {\n id: \"commet\",\n endpoints: {\n ...plugins,\n },\n init() {\n return {\n options: {\n databaseHooks: {\n user: {\n create: {\n before: onBeforeUserCreate(options),\n after: onAfterUserCreate(options),\n },\n update: {\n after: onUserUpdate(options),\n },\n delete: {\n after: onUserDelete(options),\n },\n },\n },\n },\n };\n },\n } satisfies BetterAuthPlugin;\n};\n","import type { GenericEndpointContext, User } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\nimport type { CommetOptions } from \"../types\";\n\n/**\n * Hook called before a user is created in Better Auth\n * Creates a Commet customer if createCustomerOnSignUp is enabled\n */\nexport const onBeforeUserCreate =\n (options: CommetOptions) =>\n async (user: Partial<User>, context: GenericEndpointContext | null) => {\n if (!context || !options.createCustomerOnSignUp) {\n return;\n }\n\n try {\n const customParams = options.getCustomerCreateParams\n ? await options.getCustomerCreateParams({ user }, context.request)\n : {};\n\n if (!user.email) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"An email is required to create a customer\",\n });\n }\n\n // Check if customer already exists by email\n const existingCustomers = await options.client.customers.list({\n search: user.email,\n });\n\n const existingCustomer = existingCustomers.data?.find(\n (c) => c.billingEmail === user.email,\n );\n\n // Skip creation if customer already exists\n if (!existingCustomer) {\n await options.client.customers.create({\n email: user.email,\n legalName: customParams.legalName ?? user.name,\n displayName: customParams.displayName,\n domain: customParams.domain,\n metadata: customParams.metadata,\n });\n }\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: `Commet customer creation failed: ${e.message}`,\n });\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Commet customer creation failed\",\n });\n }\n };\n\n/**\n * Hook called after a user is created in Better Auth\n * Updates the Commet customer with the externalId (Better Auth user ID)\n */\nexport const onAfterUserCreate =\n (options: CommetOptions) =>\n async (user: User, context: GenericEndpointContext | null) => {\n if (!context || !options.createCustomerOnSignUp) {\n return;\n }\n\n try {\n // Find customer by email and update with externalId\n const existingCustomers = await options.client.customers.list({\n search: user.email,\n });\n\n const existingCustomer = existingCustomers.data?.find(\n (c) => c.billingEmail === user.email,\n );\n\n if (existingCustomer && existingCustomer.externalId !== user.id) {\n await options.client.customers.update({\n customerId: existingCustomer.id,\n externalId: user.id,\n });\n }\n } catch (e: unknown) {\n if (e instanceof Error) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: `Commet customer update failed: ${e.message}`,\n });\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Commet customer update failed\",\n });\n }\n };\n\n/**\n * Hook called when a user is updated in Better Auth\n * Syncs email and name changes to the Commet customer\n */\nexport const onUserUpdate =\n (options: CommetOptions) =>\n async (user: User, context: GenericEndpointContext | null) => {\n if (!context || !options.createCustomerOnSignUp) {\n return;\n }\n\n try {\n // Find customer by externalId and update\n const existingCustomers = await options.client.customers.list({\n externalId: user.id,\n });\n\n const existingCustomer = existingCustomers.data?.[0];\n\n if (existingCustomer) {\n await options.client.customers.update({\n customerId: existingCustomer.id,\n email: user.email,\n legalName: user.name ?? undefined,\n });\n }\n } catch (e: unknown) {\n // Log but don't throw - update failures shouldn't break the auth flow\n if (e instanceof Error) {\n context.context.logger.error(\n `Commet customer update failed: ${e.message}`,\n );\n } else {\n context.context.logger.error(\"Commet customer update failed\");\n }\n }\n };\n\n/**\n * Hook called when a user is deleted in Better Auth\n * Archives the corresponding Commet customer\n */\nexport const onUserDelete =\n (options: CommetOptions) =>\n async (user: User, context: GenericEndpointContext | null) => {\n if (!context || !options.createCustomerOnSignUp) {\n return;\n }\n\n try {\n // Find customer by externalId and archive\n const existingCustomers = await options.client.customers.list({\n externalId: user.id,\n });\n\n const existingCustomer = existingCustomers.data?.[0];\n\n if (existingCustomer) {\n await options.client.customers.archive(existingCustomer.id);\n }\n } catch (e: unknown) {\n // Log but don't throw - archive failures shouldn't break the auth flow\n if (e instanceof Error) {\n context?.context.logger.error(\n `Commet customer archive failed: ${e.message}`,\n );\n } else {\n context?.context.logger.error(\"Commet customer archive failed\");\n }\n }\n };\n","import type { BetterAuthClientPlugin } from \"better-auth\";\nimport type { BetterFetchOption } from \"better-auth/client\";\nimport type { commet } from \"./index\";\n\n/**\n * Commet client plugin for Better Auth\n *\n * Provides client-side methods to interact with Commet billing features.\n *\n * @example\n * ```typescript\n * import { createAuthClient } from \"better-auth/react\";\n * import { commetClient } from \"@commet/better-auth\";\n *\n * export const authClient = createAuthClient({\n * plugins: [commetClient()]\n * });\n *\n * // Usage - you can always query state directly (no webhooks needed)\n * const { data: subscription } = await authClient.subscription.get();\n * const { data: features } = await authClient.features.list();\n * const { data: canUse } = await authClient.features.canUse(\"api_calls\");\n * await authClient.usage.track({ eventType: \"api_call\" });\n * await authClient.customer.portal(); // Redirect to portal\n * ```\n */\nexport const commetClient = () => {\n return {\n id: \"commet-client\",\n $InferServerPlugin: {} as ReturnType<typeof commet>,\n getActions: ($fetch) => {\n return {\n // Customer Portal\n customer: {\n /**\n * Redirect to the Commet customer portal\n */\n portal: async (fetchOptions?: BetterFetchOption) => {\n const res = await $fetch(\"/commet/portal\", {\n method: \"GET\",\n ...fetchOptions,\n });\n\n if (res.error) {\n throw new Error(res.error.message);\n }\n\n const data = res.data as { url: string; redirect: boolean };\n\n if (data.redirect && typeof window !== \"undefined\") {\n window.location.href = data.url;\n }\n\n return data;\n },\n },\n\n // Subscription management\n subscription: {\n /**\n * Get the current subscription for the authenticated user\n */\n get: async (fetchOptions?: BetterFetchOption) => {\n return $fetch(\"/commet/subscription\", {\n method: \"GET\",\n ...fetchOptions,\n });\n },\n\n /**\n * Change the subscription plan (upgrade/downgrade)\n */\n changePlan: async (\n data: {\n planId?: string;\n slug?: string;\n billingInterval?: \"monthly\" | \"quarterly\" | \"yearly\";\n },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/subscription/change-plan\", {\n method: \"POST\",\n body: data,\n ...fetchOptions,\n });\n },\n\n /**\n * Cancel the subscription\n */\n cancel: async (\n data?: { reason?: string; immediate?: boolean },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/subscription/cancel\", {\n method: \"POST\",\n body: data ?? {},\n ...fetchOptions,\n });\n },\n },\n\n // Feature access\n features: {\n /**\n * List all features for the authenticated user\n */\n list: async (fetchOptions?: BetterFetchOption) => {\n return $fetch(\"/commet/features\", {\n method: \"GET\",\n ...fetchOptions,\n });\n },\n\n /**\n * Get a specific feature's access/usage\n */\n get: async (code: string, fetchOptions?: BetterFetchOption) => {\n return $fetch(`/commet/features/${code}`, {\n method: \"GET\",\n ...fetchOptions,\n });\n },\n\n /**\n * Check if a feature is enabled (boolean check)\n */\n check: async (code: string, fetchOptions?: BetterFetchOption) => {\n return $fetch(`/commet/features/${code}/check`, {\n method: \"GET\",\n ...fetchOptions,\n });\n },\n\n /**\n * Check if user can use one more unit of a feature\n * Returns { allowed: boolean, willBeCharged: boolean }\n */\n canUse: async (code: string, fetchOptions?: BetterFetchOption) => {\n return $fetch(`/commet/features/${code}/can-use`, {\n method: \"GET\",\n ...fetchOptions,\n });\n },\n },\n\n // Usage tracking\n usage: {\n /**\n * Track a usage event for the authenticated user\n */\n track: async (\n data: {\n eventType: string;\n value?: number;\n idempotencyKey?: string;\n properties?: Record<string, string>;\n },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/usage/track\", {\n method: \"POST\",\n body: data,\n ...fetchOptions,\n });\n },\n },\n\n // Seat management\n seats: {\n /**\n * List all seat balances for the authenticated user\n */\n list: async (fetchOptions?: BetterFetchOption) => {\n return $fetch(\"/commet/seats\", {\n method: \"GET\",\n ...fetchOptions,\n });\n },\n\n /**\n * Add seats of a specific type\n */\n add: async (\n data: { seatType: string; count: number },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/seats/add\", {\n method: \"POST\",\n body: data,\n ...fetchOptions,\n });\n },\n\n /**\n * Remove seats of a specific type\n */\n remove: async (\n data: { seatType: string; count: number },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/seats/remove\", {\n method: \"POST\",\n body: data,\n ...fetchOptions,\n });\n },\n\n /**\n * Set seats to a specific count\n */\n set: async (\n data: { seatType: string; count: number },\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/seats/set\", {\n method: \"POST\",\n body: data,\n ...fetchOptions,\n });\n },\n\n /**\n * Set all seat types at once\n */\n setAll: async (\n seats: Record<string, number>,\n fetchOptions?: BetterFetchOption,\n ) => {\n return $fetch(\"/commet/seats/set-all\", {\n method: \"POST\",\n body: { seats },\n ...fetchOptions,\n });\n },\n },\n };\n },\n } satisfies BetterAuthClientPlugin;\n};\n","import type { Commet } from \"@commet/node\";\nimport { APIError, sessionMiddleware } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/plugins\";\n\nexport interface PortalConfig {\n /**\n * URL to return to after leaving the customer portal\n */\n returnUrl?: string;\n}\n\n/**\n * Portal plugin - Provides customer portal access\n *\n * Endpoints:\n * - GET /customer/portal - Redirects to the Commet customer portal\n */\nexport const portal =\n ({ returnUrl }: PortalConfig = {}) =>\n (commet: Commet) => {\n return {\n portal: createAuthEndpoint(\n \"/commet/portal\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to access the customer portal\",\n });\n }\n\n try {\n const portalAccess = await commet.portal.getUrl({\n externalId: userId,\n });\n\n if (!portalAccess.success || !portalAccess.data) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message:\n portalAccess.message || \"Failed to generate portal URL\",\n });\n }\n\n // Append return URL if configured\n let portalUrl = portalAccess.data.portalUrl;\n if (returnUrl) {\n const url = new URL(portalUrl);\n url.searchParams.set(\"return_url\", returnUrl);\n portalUrl = url.toString();\n }\n\n return ctx.json({\n url: portalUrl,\n redirect: true,\n });\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet portal access failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to access customer portal\",\n });\n }\n },\n ),\n };\n };\n","import type { Commet } from \"@commet/node\";\nimport { APIError, sessionMiddleware } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/plugins\";\nimport { z } from \"zod\";\n\nexport interface SubscriptionsConfig {\n /**\n * Optional plan mappings for easy slug-based plan changes\n */\n plans?: Array<{ planId: string; slug: string }>;\n}\n\nconst ChangePlanSchema = z.object({\n planId: z.string().optional(),\n slug: z.string().optional(),\n billingInterval: z.enum([\"monthly\", \"quarterly\", \"yearly\"]).optional(),\n});\n\nconst CancelSchema = z.object({\n reason: z.string().optional(),\n immediate: z.boolean().optional(),\n});\n\n/**\n * Subscriptions plugin - Manage customer subscriptions\n *\n * Endpoints:\n * - GET /subscription - Get active subscription for the authenticated user\n * - POST /subscription/change-plan - Change subscription plan (upgrade/downgrade)\n * - POST /subscription/cancel - Cancel the subscription\n */\nexport const subscriptions =\n (config: SubscriptionsConfig = {}) =>\n (commet: Commet) => {\n return {\n getSubscription: createAuthEndpoint(\n \"/commet/subscription\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to view subscription\",\n });\n }\n\n try {\n const subscription = await commet.subscriptions.get(userId);\n\n if (!subscription.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message:\n subscription.message || \"Failed to retrieve subscription\",\n });\n }\n\n return ctx.json(subscription.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet subscription get failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to retrieve subscription\",\n });\n }\n },\n ),\n\n changePlan: createAuthEndpoint(\n \"/commet/subscription/change-plan\",\n {\n method: \"POST\",\n body: ChangePlanSchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to change plan\",\n });\n }\n\n // Resolve plan ID from slug if provided\n let planId = ctx.body.planId;\n if (ctx.body.slug && !planId) {\n const plan = config.plans?.find((p) => p.slug === ctx.body.slug);\n if (!plan) {\n throw new APIError(\"BAD_REQUEST\", {\n message: `Plan with slug \"${ctx.body.slug}\" not found`,\n });\n }\n planId = plan.planId;\n }\n\n if (!planId) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Either planId or slug must be provided\",\n });\n }\n\n try {\n // First get the current subscription\n const currentSub = await commet.subscriptions.get(userId);\n\n if (!currentSub.success || !currentSub.data) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"No active subscription found\",\n });\n }\n\n const result = await commet.subscriptions.changePlan({\n subscriptionId: currentSub.data.id,\n planId,\n billingInterval: ctx.body.billingInterval,\n });\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to change plan\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet plan change failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to change plan\",\n });\n }\n },\n ),\n\n cancelSubscription: createAuthEndpoint(\n \"/commet/subscription/cancel\",\n {\n method: \"POST\",\n body: CancelSchema.optional(),\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to cancel subscription\",\n });\n }\n\n try {\n // First get the current subscription\n const currentSub = await commet.subscriptions.get(userId);\n\n if (!currentSub.success || !currentSub.data) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"No active subscription found\",\n });\n }\n\n const result = await commet.subscriptions.cancel({\n subscriptionId: currentSub.data.id,\n reason: ctx.body?.reason,\n immediate: ctx.body?.immediate,\n });\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to cancel subscription\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet subscription cancel failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to cancel subscription\",\n });\n }\n },\n ),\n };\n };\n","import type { Commet } from \"@commet/node\";\nimport { APIError, sessionMiddleware } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/plugins\";\n\nexport type FeaturesConfig = Record<string, never>;\n\n/**\n * Features plugin - Check feature access and usage\n *\n * Endpoints:\n * - GET /features - List all features for the authenticated user\n * - GET /features/:code - Get a specific feature's access/usage\n * - GET /features/:code/check - Check if feature is enabled (boolean check)\n * - GET /features/:code/can-use - Check if user can use one more unit\n */\nexport const features =\n (_config: FeaturesConfig = {}) =>\n (commet: Commet) => {\n return {\n listFeatures: createAuthEndpoint(\n \"/commet/features\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to view features\",\n });\n }\n\n try {\n const result = await commet.features.list(userId);\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to list features\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet features list failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to list features\",\n });\n }\n },\n ),\n\n getFeature: createAuthEndpoint(\n \"/commet/features/:code\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n const code = ctx.params?.code;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to view feature\",\n });\n }\n\n if (!code) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Feature code is required\",\n });\n }\n\n try {\n const result = await commet.features.get({\n externalId: userId,\n code,\n });\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to get feature\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet feature get failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to get feature\",\n });\n }\n },\n ),\n\n checkFeature: createAuthEndpoint(\n \"/commet/features/:code/check\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n const code = ctx.params?.code;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to check feature\",\n });\n }\n\n if (!code) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Feature code is required\",\n });\n }\n\n try {\n const result = await commet.features.check({\n externalId: userId,\n code,\n });\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to check feature\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet feature check failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to check feature\",\n });\n }\n },\n ),\n\n canUseFeature: createAuthEndpoint(\n \"/commet/features/:code/can-use\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n const code = ctx.params?.code;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to check feature usage\",\n });\n }\n\n if (!code) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Feature code is required\",\n });\n }\n\n try {\n const result = await commet.features.canUse({\n externalId: userId,\n code,\n });\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to check feature usage\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet feature canUse failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to check feature usage\",\n });\n }\n },\n ),\n };\n };\n","import type { Commet } from \"@commet/node\";\nimport { APIError, sessionMiddleware } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/plugins\";\nimport { z } from \"zod\";\n\nexport type UsageConfig = Record<string, never>;\n\nconst TrackEventSchema = z.object({\n eventType: z.string(),\n value: z.number().optional(),\n idempotencyKey: z.string().optional(),\n properties: z.record(z.string(), z.string()).optional(),\n});\n\n/**\n * Usage plugin - Track usage events for metered billing\n *\n * Endpoints:\n * - POST /usage/track - Track a usage event for the authenticated user\n */\nexport const usage =\n (_config: UsageConfig = {}) =>\n (commet: Commet) => {\n return {\n trackUsage: createAuthEndpoint(\n \"/commet/usage/track\",\n {\n method: \"POST\",\n body: TrackEventSchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to track usage\",\n });\n }\n\n try {\n const result = await commet.usage.track(\n {\n externalId: userId,\n eventType: ctx.body.eventType,\n idempotencyKey: ctx.body.idempotencyKey,\n properties: ctx.body.properties,\n },\n {},\n );\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to track usage\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet usage track failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to track usage\",\n });\n }\n },\n ),\n };\n };\n","import type { Commet } from \"@commet/node\";\nimport { APIError, sessionMiddleware } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/plugins\";\nimport { z } from \"zod\";\n\nexport type SeatsConfig = Record<string, never>;\n\nconst SeatOperationSchema = z.object({\n seatType: z.string(),\n count: z.number().min(1),\n});\n\nconst SetAllSeatsSchema = z.object({\n seats: z.record(z.string(), z.number()),\n});\n\n/**\n * Seats plugin - Manage seat-based licensing\n *\n * Endpoints:\n * - GET /seats - List all seat balances for the authenticated user\n * - POST /seats/add - Add seats of a specific type\n * - POST /seats/remove - Remove seats of a specific type\n * - POST /seats/set - Set seats to a specific count\n * - POST /seats/set-all - Set all seat types at once\n */\nexport const seats =\n (_config: SeatsConfig = {}) =>\n (commet: Commet) => {\n return {\n listSeats: createAuthEndpoint(\n \"/commet/seats\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to view seats\",\n });\n }\n\n try {\n const result = await commet.seats.getAllBalances({\n externalId: userId,\n });\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to list seats\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet seats list failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to list seats\",\n });\n }\n },\n ),\n\n addSeats: createAuthEndpoint(\n \"/commet/seats/add\",\n {\n method: \"POST\",\n body: SeatOperationSchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to add seats\",\n });\n }\n\n try {\n const result = await commet.seats.add(\n {\n externalId: userId,\n seatType: ctx.body.seatType,\n count: ctx.body.count,\n },\n {},\n );\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to add seats\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(`Commet seats add failed: ${e.message}`);\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to add seats\",\n });\n }\n },\n ),\n\n removeSeats: createAuthEndpoint(\n \"/commet/seats/remove\",\n {\n method: \"POST\",\n body: SeatOperationSchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to remove seats\",\n });\n }\n\n try {\n const result = await commet.seats.remove(\n {\n externalId: userId,\n seatType: ctx.body.seatType,\n count: ctx.body.count,\n },\n {},\n );\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to remove seats\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet seats remove failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to remove seats\",\n });\n }\n },\n ),\n\n setSeats: createAuthEndpoint(\n \"/commet/seats/set\",\n {\n method: \"POST\",\n body: SeatOperationSchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to set seats\",\n });\n }\n\n try {\n const result = await commet.seats.set(\n {\n externalId: userId,\n seatType: ctx.body.seatType,\n count: ctx.body.count,\n },\n {},\n );\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to set seats\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(`Commet seats set failed: ${e.message}`);\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to set seats\",\n });\n }\n },\n ),\n\n setAllSeats: createAuthEndpoint(\n \"/commet/seats/set-all\",\n {\n method: \"POST\",\n body: SetAllSeatsSchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session?.user.id;\n\n if (!userId) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to set seats\",\n });\n }\n\n try {\n const result = await commet.seats.setAll(\n {\n externalId: userId,\n seats: ctx.body.seats,\n },\n {},\n );\n\n if (!result.success) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: result.message || \"Failed to set all seats\",\n });\n }\n\n return ctx.json(result.data ?? null);\n } catch (e: unknown) {\n if (e instanceof APIError) {\n throw e;\n }\n\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet seats set-all failed: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to set all seats\",\n });\n }\n },\n ),\n };\n };\n","import type { Commet, WebhookEvent, WebhookPayload } from \"@commet/node\";\nimport { APIError, createAuthEndpoint } from \"better-auth/api\";\n\n/**\n * Webhook handler function type\n */\nexport type WebhookHandler<T = WebhookPayload> = (payload: T) => Promise<void>;\n\n/**\n * Webhooks plugin configuration\n *\n * Note: Webhooks are OPTIONAL in Commet. You can always query the current state\n * using subscriptions.get(), features.list(), etc. Webhooks are useful if you want\n * to react immediately to events without polling.\n */\nexport interface WebhooksConfig {\n /**\n * Webhook secret for signature verification\n */\n secret: string;\n /**\n * Handler for subscription.created events\n */\n onSubscriptionCreated?: WebhookHandler;\n /**\n * Handler for subscription.activated events\n */\n onSubscriptionActivated?: WebhookHandler;\n /**\n * Handler for subscription.canceled events\n */\n onSubscriptionCanceled?: WebhookHandler;\n /**\n * Handler for subscription.updated events\n */\n onSubscriptionUpdated?: WebhookHandler;\n /**\n * Generic handler for all webhook events (catch-all)\n */\n onPayload?: WebhookHandler;\n}\n\n/**\n * Map event types to their handler keys\n */\nconst EVENT_HANDLER_MAP: Record<WebhookEvent, keyof WebhooksConfig> = {\n \"subscription.created\": \"onSubscriptionCreated\",\n \"subscription.activated\": \"onSubscriptionActivated\",\n \"subscription.canceled\": \"onSubscriptionCanceled\",\n \"subscription.updated\": \"onSubscriptionUpdated\",\n};\n\n/**\n * Webhooks plugin - Handle incoming Commet webhooks (OPTIONAL)\n *\n * You can always query the current state directly:\n * - authClient.subscription.get() for subscription status\n * - authClient.features.list() for feature access\n * - authClient.features.canUse() for usage checks\n *\n * Webhooks are useful when you want to:\n * - React immediately to changes (e.g., send email on cancellation)\n * - Avoid polling latency in critical cases\n * - Audit/log events\n *\n * Endpoint:\n * - POST /commet/webhooks - Receive and process Commet webhooks\n */\nexport const webhooks = (config: WebhooksConfig) => (commet: Commet) => {\n return {\n commetWebhooks: createAuthEndpoint(\n \"/commet/webhooks\",\n {\n method: \"POST\",\n metadata: {\n isAction: false,\n },\n cloneRequest: true,\n },\n async (ctx) => {\n if (!ctx.request?.body) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Request body is required\",\n });\n }\n\n const rawBody = await ctx.request.text();\n const signature = ctx.request.headers.get(\"x-commet-signature\");\n\n // Verify webhook signature\n const payload = commet.webhooks.verifyAndParse({\n rawBody,\n signature,\n secret: config.secret,\n });\n\n if (!payload) {\n ctx.context.logger.error(\"Invalid webhook signature\");\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"Invalid webhook signature\",\n });\n }\n\n try {\n // Call specific event handler if configured\n const handlerKey = EVENT_HANDLER_MAP[payload.event];\n if (handlerKey) {\n const handler = config[handlerKey] as WebhookHandler | undefined;\n if (handler) {\n await handler(payload);\n }\n }\n\n // Always call onPayload if configured (catch-all)\n if (config.onPayload) {\n await config.onPayload(payload);\n }\n\n return ctx.json({ received: true });\n } catch (e: unknown) {\n if (e instanceof Error) {\n ctx.context.logger.error(\n `Commet webhook handler error: ${e.message}`,\n );\n } else {\n ctx.context.logger.error(\"Commet webhook handler error\");\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Webhook handler error\",\n });\n }\n },\n ),\n };\n};\n"],"mappings":"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","names":["seats","import_api","commet","import_api","import_plugins","commet","import_api","import_plugins","commet","import_api","import_plugins","import_zod","commet","import_api","import_plugins","import_zod","commet","import_api","commet"]}
package/dist/index.d.cts CHANGED
@@ -7,8 +7,7 @@ import { Commet, WebhookPayload } from '@commet/node';
7
7
  import * as better_auth from 'better-auth';
8
8
  import { User, UnionToIntersection } from 'better-auth';
9
9
 
10
- interface FeaturesConfig {
11
- }
10
+ type FeaturesConfig = Record<string, never>;
12
11
  /**
13
12
  * Features plugin - Check feature access and usage
14
13
  *
@@ -169,8 +168,7 @@ declare const portal: ({ returnUrl }?: PortalConfig) => (commet: Commet) => {
169
168
  }>;
170
169
  };
171
170
 
172
- interface SeatsConfig {
173
- }
171
+ type SeatsConfig = Record<string, never>;
174
172
  /**
175
173
  * Seats plugin - Manage seat-based licensing
176
174
  *
@@ -440,8 +438,7 @@ declare const subscriptions: (config?: SubscriptionsConfig) => (commet: Commet)
440
438
  }, _commet_node.Subscription | null>;
441
439
  };
442
440
 
443
- interface UsageConfig {
444
- }
441
+ type UsageConfig = Record<string, never>;
445
442
  /**
446
443
  * Usage plugin - Track usage events for metered billing
447
444
  *
@@ -1122,7 +1119,7 @@ declare const commet: <O extends CommetOptions>(options: O) => {
1122
1119
  * // Usage - you can always query state directly (no webhooks needed)
1123
1120
  * const { data: subscription } = await authClient.subscription.get();
1124
1121
  * const { data: features } = await authClient.features.list();
1125
- * const { data: canUse } = await authClient.features.canUse({ code: "api_calls" });
1122
+ * const { data: canUse } = await authClient.features.canUse("api_calls");
1126
1123
  * await authClient.usage.track({ eventType: "api_call" });
1127
1124
  * await authClient.customer.portal(); // Redirect to portal
1128
1125
  * ```
@@ -1209,9 +1206,7 @@ declare const commetClient: () => {
1209
1206
  /**
1210
1207
  * Get a specific feature's access/usage
1211
1208
  */
1212
- get: (data: {
1213
- code: string;
1214
- }, fetchOptions?: BetterFetchOption) => Promise<{
1209
+ get: (code: string, fetchOptions?: BetterFetchOption) => Promise<{
1215
1210
  data: unknown;
1216
1211
  error: null;
1217
1212
  } | {
@@ -1225,9 +1220,7 @@ declare const commetClient: () => {
1225
1220
  /**
1226
1221
  * Check if a feature is enabled (boolean check)
1227
1222
  */
1228
- check: (data: {
1229
- code: string;
1230
- }, fetchOptions?: BetterFetchOption) => Promise<{
1223
+ check: (code: string, fetchOptions?: BetterFetchOption) => Promise<{
1231
1224
  data: unknown;
1232
1225
  error: null;
1233
1226
  } | {
@@ -1242,9 +1235,7 @@ declare const commetClient: () => {
1242
1235
  * Check if user can use one more unit of a feature
1243
1236
  * Returns { allowed: boolean, willBeCharged: boolean }
1244
1237
  */
1245
- canUse: (data: {
1246
- code: string;
1247
- }, fetchOptions?: BetterFetchOption) => Promise<{
1238
+ canUse: (code: string, fetchOptions?: BetterFetchOption) => Promise<{
1248
1239
  data: unknown;
1249
1240
  error: null;
1250
1241
  } | {
@@ -1346,9 +1337,7 @@ declare const commetClient: () => {
1346
1337
  /**
1347
1338
  * Set all seat types at once
1348
1339
  */
1349
- setAll: (data: {
1350
- seats: Record<string, number>;
1351
- }, fetchOptions?: BetterFetchOption) => Promise<{
1340
+ setAll: (seats: Record<string, number>, fetchOptions?: BetterFetchOption) => Promise<{
1352
1341
  data: unknown;
1353
1342
  error: null;
1354
1343
  } | {
package/dist/index.d.ts CHANGED
@@ -7,8 +7,7 @@ import { Commet, WebhookPayload } from '@commet/node';
7
7
  import * as better_auth from 'better-auth';
8
8
  import { User, UnionToIntersection } from 'better-auth';
9
9
 
10
- interface FeaturesConfig {
11
- }
10
+ type FeaturesConfig = Record<string, never>;
12
11
  /**
13
12
  * Features plugin - Check feature access and usage
14
13
  *
@@ -169,8 +168,7 @@ declare const portal: ({ returnUrl }?: PortalConfig) => (commet: Commet) => {
169
168
  }>;
170
169
  };
171
170
 
172
- interface SeatsConfig {
173
- }
171
+ type SeatsConfig = Record<string, never>;
174
172
  /**
175
173
  * Seats plugin - Manage seat-based licensing
176
174
  *
@@ -440,8 +438,7 @@ declare const subscriptions: (config?: SubscriptionsConfig) => (commet: Commet)
440
438
  }, _commet_node.Subscription | null>;
441
439
  };
442
440
 
443
- interface UsageConfig {
444
- }
441
+ type UsageConfig = Record<string, never>;
445
442
  /**
446
443
  * Usage plugin - Track usage events for metered billing
447
444
  *
@@ -1122,7 +1119,7 @@ declare const commet: <O extends CommetOptions>(options: O) => {
1122
1119
  * // Usage - you can always query state directly (no webhooks needed)
1123
1120
  * const { data: subscription } = await authClient.subscription.get();
1124
1121
  * const { data: features } = await authClient.features.list();
1125
- * const { data: canUse } = await authClient.features.canUse({ code: "api_calls" });
1122
+ * const { data: canUse } = await authClient.features.canUse("api_calls");
1126
1123
  * await authClient.usage.track({ eventType: "api_call" });
1127
1124
  * await authClient.customer.portal(); // Redirect to portal
1128
1125
  * ```
@@ -1209,9 +1206,7 @@ declare const commetClient: () => {
1209
1206
  /**
1210
1207
  * Get a specific feature's access/usage
1211
1208
  */
1212
- get: (data: {
1213
- code: string;
1214
- }, fetchOptions?: BetterFetchOption) => Promise<{
1209
+ get: (code: string, fetchOptions?: BetterFetchOption) => Promise<{
1215
1210
  data: unknown;
1216
1211
  error: null;
1217
1212
  } | {
@@ -1225,9 +1220,7 @@ declare const commetClient: () => {
1225
1220
  /**
1226
1221
  * Check if a feature is enabled (boolean check)
1227
1222
  */
1228
- check: (data: {
1229
- code: string;
1230
- }, fetchOptions?: BetterFetchOption) => Promise<{
1223
+ check: (code: string, fetchOptions?: BetterFetchOption) => Promise<{
1231
1224
  data: unknown;
1232
1225
  error: null;
1233
1226
  } | {
@@ -1242,9 +1235,7 @@ declare const commetClient: () => {
1242
1235
  * Check if user can use one more unit of a feature
1243
1236
  * Returns { allowed: boolean, willBeCharged: boolean }
1244
1237
  */
1245
- canUse: (data: {
1246
- code: string;
1247
- }, fetchOptions?: BetterFetchOption) => Promise<{
1238
+ canUse: (code: string, fetchOptions?: BetterFetchOption) => Promise<{
1248
1239
  data: unknown;
1249
1240
  error: null;
1250
1241
  } | {
@@ -1346,9 +1337,7 @@ declare const commetClient: () => {
1346
1337
  /**
1347
1338
  * Set all seat types at once
1348
1339
  */
1349
- setAll: (data: {
1350
- seats: Record<string, number>;
1351
- }, fetchOptions?: BetterFetchOption) => Promise<{
1340
+ setAll: (seats: Record<string, number>, fetchOptions?: BetterFetchOption) => Promise<{
1352
1341
  data: unknown;
1353
1342
  error: null;
1354
1343
  } | {
package/dist/index.js CHANGED
@@ -190,8 +190,8 @@ var commetClient = () => {
190
190
  /**
191
191
  * Get a specific feature's access/usage
192
192
  */
193
- get: async (data, fetchOptions) => {
194
- return $fetch(`/commet/features/${data.code}`, {
193
+ get: async (code, fetchOptions) => {
194
+ return $fetch(`/commet/features/${code}`, {
195
195
  method: "GET",
196
196
  ...fetchOptions
197
197
  });
@@ -199,8 +199,8 @@ var commetClient = () => {
199
199
  /**
200
200
  * Check if a feature is enabled (boolean check)
201
201
  */
202
- check: async (data, fetchOptions) => {
203
- return $fetch(`/features/${data.code}/check`, {
202
+ check: async (code, fetchOptions) => {
203
+ return $fetch(`/commet/features/${code}/check`, {
204
204
  method: "GET",
205
205
  ...fetchOptions
206
206
  });
@@ -209,8 +209,8 @@ var commetClient = () => {
209
209
  * Check if user can use one more unit of a feature
210
210
  * Returns { allowed: boolean, willBeCharged: boolean }
211
211
  */
212
- canUse: async (data, fetchOptions) => {
213
- return $fetch(`/features/${data.code}/can-use`, {
212
+ canUse: async (code, fetchOptions) => {
213
+ return $fetch(`/commet/features/${code}/can-use`, {
214
214
  method: "GET",
215
215
  ...fetchOptions
216
216
  });
@@ -273,10 +273,10 @@ var commetClient = () => {
273
273
  /**
274
274
  * Set all seat types at once
275
275
  */
276
- setAll: async (data, fetchOptions) => {
276
+ setAll: async (seats2, fetchOptions) => {
277
277
  return $fetch("/commet/seats/set-all", {
278
278
  method: "POST",
279
- body: data,
279
+ body: { seats: seats2 },
280
280
  ...fetchOptions
281
281
  });
282
282
  }