@commet/better-auth 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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 * fullName: 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 fullName: customParams.fullName ?? user.name,\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 fullName: 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
  *
@@ -578,13 +575,9 @@ type CommetEndpoints = UnionToIntersection<ReturnType<CommetPlugin>>;
578
575
  */
579
576
  interface CustomerCreateParams {
580
577
  /**
581
- * Legal name of the customer/company
582
- */
583
- legalName?: string;
584
- /**
585
- * Display name
578
+ * Full name of the customer/company
586
579
  */
587
- displayName?: string;
580
+ fullName?: string;
588
581
  /**
589
582
  * Company domain
590
583
  */
@@ -646,7 +639,7 @@ interface CommetOptions {
646
639
  * client: commetClient,
647
640
  * createCustomerOnSignUp: true,
648
641
  * getCustomerCreateParams: ({ user }) => ({
649
- * legalName: user.name,
642
+ * fullName: user.name,
650
643
  * metadata: { source: "signup" }
651
644
  * }),
652
645
  * use: [
@@ -1122,7 +1115,7 @@ declare const commet: <O extends CommetOptions>(options: O) => {
1122
1115
  * // Usage - you can always query state directly (no webhooks needed)
1123
1116
  * const { data: subscription } = await authClient.subscription.get();
1124
1117
  * const { data: features } = await authClient.features.list();
1125
- * const { data: canUse } = await authClient.features.canUse({ code: "api_calls" });
1118
+ * const { data: canUse } = await authClient.features.canUse("api_calls");
1126
1119
  * await authClient.usage.track({ eventType: "api_call" });
1127
1120
  * await authClient.customer.portal(); // Redirect to portal
1128
1121
  * ```
@@ -1209,9 +1202,7 @@ declare const commetClient: () => {
1209
1202
  /**
1210
1203
  * Get a specific feature's access/usage
1211
1204
  */
1212
- get: (data: {
1213
- code: string;
1214
- }, fetchOptions?: BetterFetchOption) => Promise<{
1205
+ get: (code: string, fetchOptions?: BetterFetchOption) => Promise<{
1215
1206
  data: unknown;
1216
1207
  error: null;
1217
1208
  } | {
@@ -1225,9 +1216,7 @@ declare const commetClient: () => {
1225
1216
  /**
1226
1217
  * Check if a feature is enabled (boolean check)
1227
1218
  */
1228
- check: (data: {
1229
- code: string;
1230
- }, fetchOptions?: BetterFetchOption) => Promise<{
1219
+ check: (code: string, fetchOptions?: BetterFetchOption) => Promise<{
1231
1220
  data: unknown;
1232
1221
  error: null;
1233
1222
  } | {
@@ -1242,9 +1231,7 @@ declare const commetClient: () => {
1242
1231
  * Check if user can use one more unit of a feature
1243
1232
  * Returns { allowed: boolean, willBeCharged: boolean }
1244
1233
  */
1245
- canUse: (data: {
1246
- code: string;
1247
- }, fetchOptions?: BetterFetchOption) => Promise<{
1234
+ canUse: (code: string, fetchOptions?: BetterFetchOption) => Promise<{
1248
1235
  data: unknown;
1249
1236
  error: null;
1250
1237
  } | {
@@ -1346,9 +1333,7 @@ declare const commetClient: () => {
1346
1333
  /**
1347
1334
  * Set all seat types at once
1348
1335
  */
1349
- setAll: (data: {
1350
- seats: Record<string, number>;
1351
- }, fetchOptions?: BetterFetchOption) => Promise<{
1336
+ setAll: (seats: Record<string, number>, fetchOptions?: BetterFetchOption) => Promise<{
1352
1337
  data: unknown;
1353
1338
  error: null;
1354
1339
  } | {
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
  *
@@ -578,13 +575,9 @@ type CommetEndpoints = UnionToIntersection<ReturnType<CommetPlugin>>;
578
575
  */
579
576
  interface CustomerCreateParams {
580
577
  /**
581
- * Legal name of the customer/company
582
- */
583
- legalName?: string;
584
- /**
585
- * Display name
578
+ * Full name of the customer/company
586
579
  */
587
- displayName?: string;
580
+ fullName?: string;
588
581
  /**
589
582
  * Company domain
590
583
  */
@@ -646,7 +639,7 @@ interface CommetOptions {
646
639
  * client: commetClient,
647
640
  * createCustomerOnSignUp: true,
648
641
  * getCustomerCreateParams: ({ user }) => ({
649
- * legalName: user.name,
642
+ * fullName: user.name,
650
643
  * metadata: { source: "signup" }
651
644
  * }),
652
645
  * use: [
@@ -1122,7 +1115,7 @@ declare const commet: <O extends CommetOptions>(options: O) => {
1122
1115
  * // Usage - you can always query state directly (no webhooks needed)
1123
1116
  * const { data: subscription } = await authClient.subscription.get();
1124
1117
  * const { data: features } = await authClient.features.list();
1125
- * const { data: canUse } = await authClient.features.canUse({ code: "api_calls" });
1118
+ * const { data: canUse } = await authClient.features.canUse("api_calls");
1126
1119
  * await authClient.usage.track({ eventType: "api_call" });
1127
1120
  * await authClient.customer.portal(); // Redirect to portal
1128
1121
  * ```
@@ -1209,9 +1202,7 @@ declare const commetClient: () => {
1209
1202
  /**
1210
1203
  * Get a specific feature's access/usage
1211
1204
  */
1212
- get: (data: {
1213
- code: string;
1214
- }, fetchOptions?: BetterFetchOption) => Promise<{
1205
+ get: (code: string, fetchOptions?: BetterFetchOption) => Promise<{
1215
1206
  data: unknown;
1216
1207
  error: null;
1217
1208
  } | {
@@ -1225,9 +1216,7 @@ declare const commetClient: () => {
1225
1216
  /**
1226
1217
  * Check if a feature is enabled (boolean check)
1227
1218
  */
1228
- check: (data: {
1229
- code: string;
1230
- }, fetchOptions?: BetterFetchOption) => Promise<{
1219
+ check: (code: string, fetchOptions?: BetterFetchOption) => Promise<{
1231
1220
  data: unknown;
1232
1221
  error: null;
1233
1222
  } | {
@@ -1242,9 +1231,7 @@ declare const commetClient: () => {
1242
1231
  * Check if user can use one more unit of a feature
1243
1232
  * Returns { allowed: boolean, willBeCharged: boolean }
1244
1233
  */
1245
- canUse: (data: {
1246
- code: string;
1247
- }, fetchOptions?: BetterFetchOption) => Promise<{
1234
+ canUse: (code: string, fetchOptions?: BetterFetchOption) => Promise<{
1248
1235
  data: unknown;
1249
1236
  error: null;
1250
1237
  } | {
@@ -1346,9 +1333,7 @@ declare const commetClient: () => {
1346
1333
  /**
1347
1334
  * Set all seat types at once
1348
1335
  */
1349
- setAll: (data: {
1350
- seats: Record<string, number>;
1351
- }, fetchOptions?: BetterFetchOption) => Promise<{
1336
+ setAll: (seats: Record<string, number>, fetchOptions?: BetterFetchOption) => Promise<{
1352
1337
  data: unknown;
1353
1338
  error: null;
1354
1339
  } | {
package/dist/index.js CHANGED
@@ -20,8 +20,7 @@ var onBeforeUserCreate = (options) => async (user, context) => {
20
20
  if (!existingCustomer) {
21
21
  await options.client.customers.create({
22
22
  email: user.email,
23
- legalName: customParams.legalName ?? user.name,
24
- displayName: customParams.displayName,
23
+ fullName: customParams.fullName ?? user.name,
25
24
  domain: customParams.domain,
26
25
  metadata: customParams.metadata
27
26
  });
@@ -81,7 +80,7 @@ var onUserUpdate = (options) => async (user, context) => {
81
80
  await options.client.customers.update({
82
81
  customerId: existingCustomer.id,
83
82
  email: user.email,
84
- legalName: user.name ?? void 0
83
+ fullName: user.name ?? void 0
85
84
  });
86
85
  }
87
86
  } catch (e) {
@@ -190,8 +189,8 @@ var commetClient = () => {
190
189
  /**
191
190
  * Get a specific feature's access/usage
192
191
  */
193
- get: async (data, fetchOptions) => {
194
- return $fetch(`/commet/features/${data.code}`, {
192
+ get: async (code, fetchOptions) => {
193
+ return $fetch(`/commet/features/${code}`, {
195
194
  method: "GET",
196
195
  ...fetchOptions
197
196
  });
@@ -199,8 +198,8 @@ var commetClient = () => {
199
198
  /**
200
199
  * Check if a feature is enabled (boolean check)
201
200
  */
202
- check: async (data, fetchOptions) => {
203
- return $fetch(`/features/${data.code}/check`, {
201
+ check: async (code, fetchOptions) => {
202
+ return $fetch(`/commet/features/${code}/check`, {
204
203
  method: "GET",
205
204
  ...fetchOptions
206
205
  });
@@ -209,8 +208,8 @@ var commetClient = () => {
209
208
  * Check if user can use one more unit of a feature
210
209
  * Returns { allowed: boolean, willBeCharged: boolean }
211
210
  */
212
- canUse: async (data, fetchOptions) => {
213
- return $fetch(`/features/${data.code}/can-use`, {
211
+ canUse: async (code, fetchOptions) => {
212
+ return $fetch(`/commet/features/${code}/can-use`, {
214
213
  method: "GET",
215
214
  ...fetchOptions
216
215
  });
@@ -273,10 +272,10 @@ var commetClient = () => {
273
272
  /**
274
273
  * Set all seat types at once
275
274
  */
276
- setAll: async (data, fetchOptions) => {
275
+ setAll: async (seats2, fetchOptions) => {
277
276
  return $fetch("/commet/seats/set-all", {
278
277
  method: "POST",
279
- body: data,
278
+ body: { seats: seats2 },
280
279
  ...fetchOptions
281
280
  });
282
281
  }