@commet/better-auth 1.3.3 → 1.3.4

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 * 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({ feature: \"api_call\", value: 1 });\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 * 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 feature: 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 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/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 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 feature: 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 feature: ctx.body.feature,\n value: ctx.body.value,\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"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/hooks/customer.ts","../src/client.ts","../src/plugins/features.ts","../src/plugins/portal.ts","../src/plugins/seats.ts","../src/plugins/subscriptions.ts","../src/plugins/usage.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\";\nexport type { FeaturesConfig } from \"./plugins/features\";\nexport { features } from \"./plugins/features\";\nexport type { PortalConfig } from \"./plugins/portal\";\n// Re-export all plugins\nexport { portal } from \"./plugins/portal\";\nexport type { SeatsConfig } from \"./plugins/seats\";\nexport { seats } from \"./plugins/seats\";\nexport type { SubscriptionsConfig } from \"./plugins/subscriptions\";\nexport { subscriptions } from \"./plugins/subscriptions\";\nexport type { UsageConfig } from \"./plugins/usage\";\nexport { usage } from \"./plugins/usage\";\nexport type { WebhookHandler, WebhooksConfig } from \"./plugins/webhooks\";\nexport { webhooks } from \"./plugins/webhooks\";\n\n// Re-export types\nexport type {\n CommetEndpoints,\n CommetOptions,\n CommetPlugin,\n CommetPlugins,\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({ feature: \"api_call\", value: 1 });\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 * 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 feature: 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 {\n APIError,\n createAuthEndpoint,\n sessionMiddleware,\n} from \"better-auth/api\";\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 {\n APIError,\n createAuthEndpoint,\n sessionMiddleware,\n} from \"better-auth/api\";\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 {\n APIError,\n createAuthEndpoint,\n sessionMiddleware,\n} from \"better-auth/api\";\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 } from \"@commet/node\";\nimport {\n APIError,\n createAuthEndpoint,\n sessionMiddleware,\n} from \"better-auth/api\";\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 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/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 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 {\n APIError,\n createAuthEndpoint,\n sessionMiddleware,\n} from \"better-auth/api\";\nimport { z } from \"zod\";\n\nexport type UsageConfig = Record<string, never>;\n\nconst TrackEventSchema = z.object({\n feature: 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 feature: ctx.body.feature,\n value: ctx.body.value,\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, 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","commet","import_api","commet","import_api","import_zod","commet","import_api","import_zod","commet","import_api","commet"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as better_auth_client from 'better-auth/client';
2
2
  import { BetterFetchOption } from 'better-auth/client';
3
+ import * as zod_v4_core from 'zod/v4/core';
3
4
  import * as zod from 'zod';
4
5
  import { z } from 'zod';
5
6
  import * as _commet_node from '@commet/node';
@@ -43,8 +44,6 @@ declare const features: (_config?: FeaturesConfig) => (commet: Commet) => {
43
44
  };
44
45
  };
45
46
  }>)[];
46
- } & {
47
- use: any[];
48
47
  }, _commet_node.FeatureAccess[] | null>;
49
48
  getFeature: better_auth.StrictEndpoint<"/commet/features/:code", {
50
49
  method: "GET";
@@ -71,8 +70,6 @@ declare const features: (_config?: FeaturesConfig) => (commet: Commet) => {
71
70
  };
72
71
  };
73
72
  }>)[];
74
- } & {
75
- use: any[];
76
73
  }, _commet_node.FeatureAccess | null>;
77
74
  checkFeature: better_auth.StrictEndpoint<"/commet/features/:code/check", {
78
75
  method: "GET";
@@ -99,8 +96,6 @@ declare const features: (_config?: FeaturesConfig) => (commet: Commet) => {
99
96
  };
100
97
  };
101
98
  }>)[];
102
- } & {
103
- use: any[];
104
99
  }, _commet_node.CheckResult | null>;
105
100
  canUseFeature: better_auth.StrictEndpoint<"/commet/features/:code/can-use", {
106
101
  method: "GET";
@@ -127,8 +122,6 @@ declare const features: (_config?: FeaturesConfig) => (commet: Commet) => {
127
122
  };
128
123
  };
129
124
  }>)[];
130
- } & {
131
- use: any[];
132
125
  }, _commet_node.CanUseResult | null>;
133
126
  };
134
127
 
@@ -170,8 +163,6 @@ declare const portal: ({ returnUrl }?: PortalConfig) => (commet: Commet) => {
170
163
  };
171
164
  };
172
165
  }>)[];
173
- } & {
174
- use: any[];
175
166
  }, {
176
167
  url: string;
177
168
  redirect: boolean;
@@ -215,8 +206,6 @@ declare const seats: (_config?: SeatsConfig) => (commet: Commet) => {
215
206
  };
216
207
  };
217
208
  }>)[];
218
- } & {
219
- use: any[];
220
209
  }, Record<string, _commet_node.SeatBalance> | null>;
221
210
  addSeats: better_auth.StrictEndpoint<"/commet/seats/add", {
222
211
  method: "POST";
@@ -247,8 +236,6 @@ declare const seats: (_config?: SeatsConfig) => (commet: Commet) => {
247
236
  };
248
237
  };
249
238
  }>)[];
250
- } & {
251
- use: any[];
252
239
  }, _commet_node.SeatEvent | null>;
253
240
  removeSeats: better_auth.StrictEndpoint<"/commet/seats/remove", {
254
241
  method: "POST";
@@ -279,8 +266,6 @@ declare const seats: (_config?: SeatsConfig) => (commet: Commet) => {
279
266
  };
280
267
  };
281
268
  }>)[];
282
- } & {
283
- use: any[];
284
269
  }, _commet_node.SeatEvent | null>;
285
270
  setSeats: better_auth.StrictEndpoint<"/commet/seats/set", {
286
271
  method: "POST";
@@ -311,8 +296,6 @@ declare const seats: (_config?: SeatsConfig) => (commet: Commet) => {
311
296
  };
312
297
  };
313
298
  }>)[];
314
- } & {
315
- use: any[];
316
299
  }, _commet_node.SeatEvent | null>;
317
300
  setAllSeats: better_auth.StrictEndpoint<"/commet/seats/set-all", {
318
301
  method: "POST";
@@ -342,8 +325,6 @@ declare const seats: (_config?: SeatsConfig) => (commet: Commet) => {
342
325
  };
343
326
  };
344
327
  }>)[];
345
- } & {
346
- use: any[];
347
328
  }, _commet_node.SeatEvent[] | null>;
348
329
  };
349
330
 
@@ -363,7 +344,7 @@ interface SubscriptionsConfig {
363
344
  * - GET /subscription - Get active subscription for the authenticated user
364
345
  * - POST /subscription/cancel - Cancel the subscription
365
346
  */
366
- declare const subscriptions: (config?: SubscriptionsConfig) => (commet: Commet) => {
347
+ declare const subscriptions: (_config?: SubscriptionsConfig) => (commet: Commet) => {
367
348
  getSubscription: better_auth.StrictEndpoint<"/commet/subscription", {
368
349
  method: "GET";
369
350
  use: ((inputContext: better_auth.MiddlewareInputContext<better_auth.MiddlewareOptions>) => Promise<{
@@ -389,8 +370,6 @@ declare const subscriptions: (config?: SubscriptionsConfig) => (commet: Commet)
389
370
  };
390
371
  };
391
372
  }>)[];
392
- } & {
393
- use: any[];
394
373
  }, _commet_node.ActiveSubscription | null>;
395
374
  cancelSubscription: better_auth.StrictEndpoint<"/commet/subscription/cancel", {
396
375
  method: "POST";
@@ -421,8 +400,6 @@ declare const subscriptions: (config?: SubscriptionsConfig) => (commet: Commet)
421
400
  };
422
401
  };
423
402
  }>)[];
424
- } & {
425
- use: any[];
426
403
  }, _commet_node.Subscription | null>;
427
404
  };
428
405
 
@@ -465,8 +442,6 @@ declare const usage: (_config?: UsageConfig) => (commet: Commet) => {
465
442
  };
466
443
  };
467
444
  }>)[];
468
- } & {
469
- use: any[];
470
445
  }, _commet_node.UsageEvent | null>;
471
446
  };
472
447
 
@@ -530,8 +505,6 @@ declare const webhooks: (config: WebhooksConfig) => (commet: Commet) => {
530
505
  isAction: false;
531
506
  };
532
507
  cloneRequest: true;
533
- } & {
534
- use: any[];
535
508
  }, {
536
509
  received: boolean;
537
510
  }>;
@@ -679,8 +652,6 @@ declare const commet: <O extends CommetOptions>(options: O) => {
679
652
  };
680
653
  };
681
654
  }>)[];
682
- } & {
683
- use: any[];
684
655
  }, {
685
656
  url: string;
686
657
  redirect: boolean;
@@ -711,15 +682,13 @@ declare const commet: <O extends CommetOptions>(options: O) => {
711
682
  };
712
683
  };
713
684
  }>)[];
714
- } & {
715
- use: any[];
716
685
  }, _commet_node.ActiveSubscription | null>;
717
686
  cancelSubscription: better_auth.StrictEndpoint<"/commet/subscription/cancel", {
718
687
  method: "POST";
719
688
  body: zod.ZodOptional<zod.ZodObject<{
720
689
  reason: zod.ZodOptional<zod.ZodString>;
721
690
  immediate: zod.ZodOptional<zod.ZodBoolean>;
722
- }, better_auth.$strip>>;
691
+ }, zod_v4_core.$strip>>;
723
692
  use: ((inputContext: better_auth.MiddlewareInputContext<better_auth.MiddlewareOptions>) => Promise<{
724
693
  session: {
725
694
  session: Record<string, any> & {
@@ -743,8 +712,6 @@ declare const commet: <O extends CommetOptions>(options: O) => {
743
712
  };
744
713
  };
745
714
  }>)[];
746
- } & {
747
- use: any[];
748
715
  }, _commet_node.Subscription | null>;
749
716
  } | {
750
717
  listFeatures: better_auth.StrictEndpoint<"/commet/features", {
@@ -772,8 +739,6 @@ declare const commet: <O extends CommetOptions>(options: O) => {
772
739
  };
773
740
  };
774
741
  }>)[];
775
- } & {
776
- use: any[];
777
742
  }, _commet_node.FeatureAccess[] | null>;
778
743
  getFeature: better_auth.StrictEndpoint<"/commet/features/:code", {
779
744
  method: "GET";
@@ -800,8 +765,6 @@ declare const commet: <O extends CommetOptions>(options: O) => {
800
765
  };
801
766
  };
802
767
  }>)[];
803
- } & {
804
- use: any[];
805
768
  }, _commet_node.FeatureAccess | null>;
806
769
  checkFeature: better_auth.StrictEndpoint<"/commet/features/:code/check", {
807
770
  method: "GET";
@@ -828,8 +791,6 @@ declare const commet: <O extends CommetOptions>(options: O) => {
828
791
  };
829
792
  };
830
793
  }>)[];
831
- } & {
832
- use: any[];
833
794
  }, _commet_node.CheckResult | null>;
834
795
  canUseFeature: better_auth.StrictEndpoint<"/commet/features/:code/can-use", {
835
796
  method: "GET";
@@ -856,8 +817,6 @@ declare const commet: <O extends CommetOptions>(options: O) => {
856
817
  };
857
818
  };
858
819
  }>)[];
859
- } & {
860
- use: any[];
861
820
  }, _commet_node.CanUseResult | null>;
862
821
  } | {
863
822
  trackUsage: better_auth.StrictEndpoint<"/commet/usage/track", {
@@ -867,7 +826,7 @@ declare const commet: <O extends CommetOptions>(options: O) => {
867
826
  value: zod.ZodOptional<zod.ZodNumber>;
868
827
  idempotencyKey: zod.ZodOptional<zod.ZodString>;
869
828
  properties: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
870
- }, better_auth.$strip>;
829
+ }, zod_v4_core.$strip>;
871
830
  use: ((inputContext: better_auth.MiddlewareInputContext<better_auth.MiddlewareOptions>) => Promise<{
872
831
  session: {
873
832
  session: Record<string, any> & {
@@ -891,8 +850,6 @@ declare const commet: <O extends CommetOptions>(options: O) => {
891
850
  };
892
851
  };
893
852
  }>)[];
894
- } & {
895
- use: any[];
896
853
  }, _commet_node.UsageEvent | null>;
897
854
  } | {
898
855
  listSeats: better_auth.StrictEndpoint<"/commet/seats", {
@@ -920,15 +877,13 @@ declare const commet: <O extends CommetOptions>(options: O) => {
920
877
  };
921
878
  };
922
879
  }>)[];
923
- } & {
924
- use: any[];
925
880
  }, Record<string, _commet_node.SeatBalance> | null>;
926
881
  addSeats: better_auth.StrictEndpoint<"/commet/seats/add", {
927
882
  method: "POST";
928
883
  body: zod.ZodObject<{
929
884
  seatType: zod.ZodString;
930
885
  count: zod.ZodNumber;
931
- }, better_auth.$strip>;
886
+ }, zod_v4_core.$strip>;
932
887
  use: ((inputContext: better_auth.MiddlewareInputContext<better_auth.MiddlewareOptions>) => Promise<{
933
888
  session: {
934
889
  session: Record<string, any> & {
@@ -952,15 +907,13 @@ declare const commet: <O extends CommetOptions>(options: O) => {
952
907
  };
953
908
  };
954
909
  }>)[];
955
- } & {
956
- use: any[];
957
910
  }, _commet_node.SeatEvent | null>;
958
911
  removeSeats: better_auth.StrictEndpoint<"/commet/seats/remove", {
959
912
  method: "POST";
960
913
  body: zod.ZodObject<{
961
914
  seatType: zod.ZodString;
962
915
  count: zod.ZodNumber;
963
- }, better_auth.$strip>;
916
+ }, zod_v4_core.$strip>;
964
917
  use: ((inputContext: better_auth.MiddlewareInputContext<better_auth.MiddlewareOptions>) => Promise<{
965
918
  session: {
966
919
  session: Record<string, any> & {
@@ -984,15 +937,13 @@ declare const commet: <O extends CommetOptions>(options: O) => {
984
937
  };
985
938
  };
986
939
  }>)[];
987
- } & {
988
- use: any[];
989
940
  }, _commet_node.SeatEvent | null>;
990
941
  setSeats: better_auth.StrictEndpoint<"/commet/seats/set", {
991
942
  method: "POST";
992
943
  body: zod.ZodObject<{
993
944
  seatType: zod.ZodString;
994
945
  count: zod.ZodNumber;
995
- }, better_auth.$strip>;
946
+ }, zod_v4_core.$strip>;
996
947
  use: ((inputContext: better_auth.MiddlewareInputContext<better_auth.MiddlewareOptions>) => Promise<{
997
948
  session: {
998
949
  session: Record<string, any> & {
@@ -1016,14 +967,12 @@ declare const commet: <O extends CommetOptions>(options: O) => {
1016
967
  };
1017
968
  };
1018
969
  }>)[];
1019
- } & {
1020
- use: any[];
1021
970
  }, _commet_node.SeatEvent | null>;
1022
971
  setAllSeats: better_auth.StrictEndpoint<"/commet/seats/set-all", {
1023
972
  method: "POST";
1024
973
  body: zod.ZodObject<{
1025
974
  seats: zod.ZodRecord<zod.ZodString, zod.ZodNumber>;
1026
- }, better_auth.$strip>;
975
+ }, zod_v4_core.$strip>;
1027
976
  use: ((inputContext: better_auth.MiddlewareInputContext<better_auth.MiddlewareOptions>) => Promise<{
1028
977
  session: {
1029
978
  session: Record<string, any> & {
@@ -1047,8 +996,6 @@ declare const commet: <O extends CommetOptions>(options: O) => {
1047
996
  };
1048
997
  };
1049
998
  }>)[];
1050
- } & {
1051
- use: any[];
1052
999
  }, _commet_node.SeatEvent[] | null>;
1053
1000
  } | {
1054
1001
  commetWebhooks: better_auth.StrictEndpoint<"/commet/webhooks", {
@@ -1057,8 +1004,6 @@ declare const commet: <O extends CommetOptions>(options: O) => {
1057
1004
  isAction: false;
1058
1005
  };
1059
1006
  cloneRequest: true;
1060
- } & {
1061
- use: any[];
1062
1007
  }, {
1063
1008
  received: boolean;
1064
1009
  }>;