@commet/better-auth 1.2.4 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -185,12 +185,6 @@ await authClient.customer.portal();
185
185
  const { data: subscription } = await authClient.subscription.get();
186
186
  console.log(subscription?.status); // "active", "trialing", etc.
187
187
 
188
- // Change plan (upgrade/downgrade)
189
- await authClient.subscription.changePlan({
190
- planId: "plan_456", // or use slug if configured
191
- billingInterval: "yearly"
192
- });
193
-
194
188
  // Cancel subscription
195
189
  await authClient.subscription.cancel({
196
190
  reason: "switching_to_competitor",
@@ -280,7 +274,6 @@ All endpoints are prefixed with `/commet/` to avoid collisions with other plugin
280
274
  |--------|----------|--------|-------------|
281
275
  | portal | `/commet/portal` | GET | Generates portal URL and redirects |
282
276
  | subscriptions | `/commet/subscription` | GET | Gets active subscription |
283
- | subscriptions | `/commet/subscription/change-plan` | POST | Changes plan |
284
277
  | subscriptions | `/commet/subscription/cancel` | POST | Cancels subscription |
285
278
  | features | `/commet/features` | GET | Lists all features |
286
279
  | features | `/commet/features/:code` | GET | Gets a specific feature |
@@ -303,4 +296,3 @@ All endpoints are prefixed with `/commet/` to avoid collisions with other plugin
303
296
  ## License
304
297
 
305
298
  MIT
306
-
package/dist/client.cjs CHANGED
@@ -60,16 +60,6 @@ var commetClient = () => {
60
60
  ...fetchOptions
61
61
  });
62
62
  },
63
- /**
64
- * Change the subscription plan (upgrade/downgrade)
65
- */
66
- changePlan: async (data, fetchOptions) => {
67
- return $fetch("/commet/subscription/change-plan", {
68
- method: "POST",
69
- body: data,
70
- ...fetchOptions
71
- });
72
- },
73
63
  /**
74
64
  * Cancel the subscription
75
65
  */
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts"],"sourcesContent":["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 * 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 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"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client.ts"],"sourcesContent":["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"],"mappings":"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","names":[]}
package/dist/client.js CHANGED
@@ -36,16 +36,6 @@ var commetClient = () => {
36
36
  ...fetchOptions
37
37
  });
38
38
  },
39
- /**
40
- * Change the subscription plan (upgrade/downgrade)
41
- */
42
- changePlan: async (data, fetchOptions) => {
43
- return $fetch("/commet/subscription/change-plan", {
44
- method: "POST",
45
- body: data,
46
- ...fetchOptions
47
- });
48
- },
49
39
  /**
50
40
  * Cancel the subscription
51
41
  */
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts"],"sourcesContent":["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 * 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 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"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client.ts"],"sourcesContent":["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"],"mappings":"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","names":[]}
package/dist/index.cjs CHANGED
@@ -187,16 +187,6 @@ var commetClient = () => {
187
187
  ...fetchOptions
188
188
  });
189
189
  },
190
- /**
191
- * Change the subscription plan (upgrade/downgrade)
192
- */
193
- changePlan: async (data, fetchOptions) => {
194
- return $fetch("/commet/subscription/change-plan", {
195
- method: "POST",
196
- body: data,
197
- ...fetchOptions
198
- });
199
- },
200
190
  /**
201
191
  * Cancel the subscription
202
192
  */
@@ -377,11 +367,6 @@ var portal = ({ returnUrl } = {}) => (commet2) => {
377
367
  var import_api3 = require("better-auth/api");
378
368
  var import_plugins2 = require("better-auth/plugins");
379
369
  var import_zod = require("zod");
380
- var ChangePlanSchema = import_zod.z.object({
381
- planId: import_zod.z.string().optional(),
382
- slug: import_zod.z.string().optional(),
383
- billingInterval: import_zod.z.enum(["monthly", "quarterly", "yearly"]).optional()
384
- });
385
370
  var CancelSchema = import_zod.z.object({
386
371
  reason: import_zod.z.string().optional(),
387
372
  immediate: import_zod.z.boolean().optional()
@@ -424,68 +409,6 @@ var subscriptions = (config = {}) => (commet2) => {
424
409
  }
425
410
  }
426
411
  ),
427
- changePlan: (0, import_plugins2.createAuthEndpoint)(
428
- "/commet/subscription/change-plan",
429
- {
430
- method: "POST",
431
- body: ChangePlanSchema,
432
- use: [import_api3.sessionMiddleware]
433
- },
434
- async (ctx) => {
435
- const userId = ctx.context.session?.user.id;
436
- if (!userId) {
437
- throw new import_api3.APIError("UNAUTHORIZED", {
438
- message: "You must be logged in to change plan"
439
- });
440
- }
441
- let planId = ctx.body.planId;
442
- if (ctx.body.slug && !planId) {
443
- const plan = config.plans?.find((p) => p.slug === ctx.body.slug);
444
- if (!plan) {
445
- throw new import_api3.APIError("BAD_REQUEST", {
446
- message: `Plan with slug "${ctx.body.slug}" not found`
447
- });
448
- }
449
- planId = plan.planId;
450
- }
451
- if (!planId) {
452
- throw new import_api3.APIError("BAD_REQUEST", {
453
- message: "Either planId or slug must be provided"
454
- });
455
- }
456
- try {
457
- const currentSub = await commet2.subscriptions.get(userId);
458
- if (!currentSub.success || !currentSub.data) {
459
- throw new import_api3.APIError("BAD_REQUEST", {
460
- message: "No active subscription found"
461
- });
462
- }
463
- const result = await commet2.subscriptions.changePlan({
464
- subscriptionId: currentSub.data.id,
465
- planId,
466
- billingInterval: ctx.body.billingInterval
467
- });
468
- if (!result.success) {
469
- throw new import_api3.APIError("INTERNAL_SERVER_ERROR", {
470
- message: result.message || "Failed to change plan"
471
- });
472
- }
473
- return ctx.json(result.data ?? null);
474
- } catch (e) {
475
- if (e instanceof import_api3.APIError) {
476
- throw e;
477
- }
478
- if (e instanceof Error) {
479
- ctx.context.logger.error(
480
- `Commet plan change failed: ${e.message}`
481
- );
482
- }
483
- throw new import_api3.APIError("INTERNAL_SERVER_ERROR", {
484
- message: "Failed to change plan"
485
- });
486
- }
487
- }
488
- ),
489
412
  cancelSubscription: (0, import_plugins2.createAuthEndpoint)(
490
413
  "/commet/subscription/cancel",
491
414
  {
@@ -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 * 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 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 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 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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,iBAAyB;AAOlB,IAAM,qBACX,CAAC,YACD,OAAO,MAAqB,YAA2C;AACrE,MAAI,CAAC,WAAW,CAAC,QAAQ,wBAAwB;AAC/C;AAAA,EACF;AAEA,MAAI;AACF,UAAM,eAAe,QAAQ,0BACzB,MAAM,QAAQ,wBAAwB,EAAE,KAAK,GAAG,QAAQ,OAAO,IAC/D,CAAC;AAEL,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI,oBAAS,eAAe;AAAA,QAChC,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAGA,UAAM,oBAAoB,MAAM,QAAQ,OAAO,UAAU,KAAK;AAAA,MAC5D,QAAQ,KAAK;AAAA,IACf,CAAC;AAED,UAAM,mBAAmB,kBAAkB,MAAM;AAAA,MAC/C,CAAC,MAAM,EAAE,iBAAiB,KAAK;AAAA,IACjC;AAGA,QAAI,CAAC,kBAAkB;AACrB,YAAM,QAAQ,OAAO,UAAU,OAAO;AAAA,QACpC,OAAO,KAAK;AAAA,QACZ,UAAU,aAAa,YAAY,KAAK;AAAA,QACxC,QAAQ,aAAa;AAAA,QACrB,UAAU,aAAa;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF,SAAS,GAAY;AACnB,QAAI,aAAa,qBAAU;AACzB,YAAM;AAAA,IACR;AAEA,QAAI,aAAa,OAAO;AACtB,YAAM,IAAI,oBAAS,yBAAyB;AAAA,QAC1C,SAAS,oCAAoC,EAAE,OAAO;AAAA,MACxD,CAAC;AAAA,IACH;AAEA,UAAM,IAAI,oBAAS,yBAAyB;AAAA,MAC1C,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;AAMK,IAAM,oBACX,CAAC,YACD,OAAO,MAAY,YAA2C;AAC5D,MAAI,CAAC,WAAW,CAAC,QAAQ,wBAAwB;AAC/C;AAAA,EACF;AAEA,MAAI;AAEF,UAAM,oBAAoB,MAAM,QAAQ,OAAO,UAAU,KAAK;AAAA,MAC5D,QAAQ,KAAK;AAAA,IACf,CAAC;AAED,UAAM,mBAAmB,kBAAkB,MAAM;AAAA,MAC/C,CAAC,MAAM,EAAE,iBAAiB,KAAK;AAAA,IACjC;AAEA,QAAI,oBAAoB,iBAAiB,eAAe,KAAK,IAAI;AAC/D,YAAM,QAAQ,OAAO,UAAU,OAAO;AAAA,QACpC,YAAY,iBAAiB;AAAA,QAC7B,YAAY,KAAK;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,EACF,SAAS,GAAY;AACnB,QAAI,aAAa,OAAO;AACtB,YAAM,IAAI,oBAAS,yBAAyB;AAAA,QAC1C,SAAS,kCAAkC,EAAE,OAAO;AAAA,MACtD,CAAC;AAAA,IACH;AAEA,UAAM,IAAI,oBAAS,yBAAyB;AAAA,MAC1C,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;AAMK,IAAM,eACX,CAAC,YACD,OAAO,MAAY,YAA2C;AAC5D,MAAI,CAAC,WAAW,CAAC,QAAQ,wBAAwB;AAC/C;AAAA,EACF;AAEA,MAAI;AAEF,UAAM,oBAAoB,MAAM,QAAQ,OAAO,UAAU,KAAK;AAAA,MAC5D,YAAY,KAAK;AAAA,IACnB,CAAC;AAED,UAAM,mBAAmB,kBAAkB,OAAO,CAAC;AAEnD,QAAI,kBAAkB;AACpB,YAAM,QAAQ,OAAO,UAAU,OAAO;AAAA,QACpC,YAAY,iBAAiB;AAAA,QAC7B,OAAO,KAAK;AAAA,QACZ,UAAU,KAAK,QAAQ;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF,SAAS,GAAY;AAEnB,QAAI,aAAa,OAAO;AACtB,cAAQ,QAAQ,OAAO;AAAA,QACrB,kCAAkC,EAAE,OAAO;AAAA,MAC7C;AAAA,IACF,OAAO;AACL,cAAQ,QAAQ,OAAO,MAAM,+BAA+B;AAAA,IAC9D;AAAA,EACF;AACF;AAMK,IAAM,eACX,CAAC,YACD,OAAO,MAAY,YAA2C;AAC5D,MAAI,CAAC,WAAW,CAAC,QAAQ,wBAAwB;AAC/C;AAAA,EACF;AAEA,MAAI;AAEF,UAAM,oBAAoB,MAAM,QAAQ,OAAO,UAAU,KAAK;AAAA,MAC5D,YAAY,KAAK;AAAA,IACnB,CAAC;AAED,UAAM,mBAAmB,kBAAkB,OAAO,CAAC;AAEnD,QAAI,kBAAkB;AACpB,YAAM,QAAQ,OAAO,UAAU,QAAQ,iBAAiB,EAAE;AAAA,IAC5D;AAAA,EACF,SAAS,GAAY;AAEnB,QAAI,aAAa,OAAO;AACtB,eAAS,QAAQ,OAAO;AAAA,QACtB,mCAAmC,EAAE,OAAO;AAAA,MAC9C;AAAA,IACF,OAAO;AACL,eAAS,QAAQ,OAAO,MAAM,gCAAgC;AAAA,IAChE;AAAA,EACF;AACF;;;ACjJK,IAAM,eAAe,MAAM;AAChC,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,oBAAoB,CAAC;AAAA,IACrB,YAAY,CAAC,WAAW;AACtB,aAAO;AAAA;AAAA,QAEL,UAAU;AAAA;AAAA;AAAA;AAAA,UAIR,QAAQ,OAAO,iBAAqC;AAClD,kBAAM,MAAM,MAAM,OAAO,kBAAkB;AAAA,cACzC,QAAQ;AAAA,cACR,GAAG;AAAA,YACL,CAAC;AAED,gBAAI,IAAI,OAAO;AACb,oBAAM,IAAI,MAAM,IAAI,MAAM,OAAO;AAAA,YACnC;AAEA,kBAAM,OAAO,IAAI;AAEjB,gBAAI,KAAK,YAAY,OAAO,WAAW,aAAa;AAClD,qBAAO,SAAS,OAAO,KAAK;AAAA,YAC9B;AAEA,mBAAO;AAAA,UACT;AAAA,QACF;AAAA;AAAA,QAGA,cAAc;AAAA;AAAA;AAAA;AAAA,UAIZ,KAAK,OAAO,iBAAqC;AAC/C,mBAAO,OAAO,wBAAwB;AAAA,cACpC,QAAQ;AAAA,cACR,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA;AAAA;AAAA;AAAA,UAKA,YAAY,OACV,MAKA,iBACG;AACH,mBAAO,OAAO,oCAAoC;AAAA,cAChD,QAAQ;AAAA,cACR,MAAM;AAAA,cACN,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA;AAAA;AAAA;AAAA,UAKA,QAAQ,OACN,MACA,iBACG;AACH,mBAAO,OAAO,+BAA+B;AAAA,cAC3C,QAAQ;AAAA,cACR,MAAM,QAAQ,CAAC;AAAA,cACf,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA,QACF;AAAA;AAAA,QAGA,UAAU;AAAA;AAAA;AAAA;AAAA,UAIR,MAAM,OAAO,iBAAqC;AAChD,mBAAO,OAAO,oBAAoB;AAAA,cAChC,QAAQ;AAAA,cACR,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA;AAAA;AAAA;AAAA,UAKA,KAAK,OAAO,MAAc,iBAAqC;AAC7D,mBAAO,OAAO,oBAAoB,IAAI,IAAI;AAAA,cACxC,QAAQ;AAAA,cACR,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA;AAAA;AAAA;AAAA,UAKA,OAAO,OAAO,MAAc,iBAAqC;AAC/D,mBAAO,OAAO,oBAAoB,IAAI,UAAU;AAAA,cAC9C,QAAQ;AAAA,cACR,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA;AAAA;AAAA;AAAA;AAAA,UAMA,QAAQ,OAAO,MAAc,iBAAqC;AAChE,mBAAO,OAAO,oBAAoB,IAAI,YAAY;AAAA,cAChD,QAAQ;AAAA,cACR,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA,QACF;AAAA;AAAA,QAGA,OAAO;AAAA;AAAA;AAAA;AAAA,UAIL,OAAO,OACL,MAMA,iBACG;AACH,mBAAO,OAAO,uBAAuB;AAAA,cACnC,QAAQ;AAAA,cACR,MAAM;AAAA,cACN,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA,QACF;AAAA;AAAA,QAGA,OAAO;AAAA;AAAA;AAAA;AAAA,UAIL,MAAM,OAAO,iBAAqC;AAChD,mBAAO,OAAO,iBAAiB;AAAA,cAC7B,QAAQ;AAAA,cACR,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA;AAAA;AAAA;AAAA,UAKA,KAAK,OACH,MACA,iBACG;AACH,mBAAO,OAAO,qBAAqB;AAAA,cACjC,QAAQ;AAAA,cACR,MAAM;AAAA,cACN,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA;AAAA;AAAA;AAAA,UAKA,QAAQ,OACN,MACA,iBACG;AACH,mBAAO,OAAO,wBAAwB;AAAA,cACpC,QAAQ;AAAA,cACR,MAAM;AAAA,cACN,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA;AAAA;AAAA;AAAA,UAKA,KAAK,OACH,MACA,iBACG;AACH,mBAAO,OAAO,qBAAqB;AAAA,cACjC,QAAQ;AAAA,cACR,MAAM;AAAA,cACN,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA;AAAA;AAAA;AAAA,UAKA,QAAQ,OACNA,QACA,iBACG;AACH,mBAAO,OAAO,yBAAyB;AAAA,cACrC,QAAQ;AAAA,cACR,MAAM,EAAE,OAAAA,OAAM;AAAA,cACd,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC9OA,IAAAC,cAA4C;AAC5C,qBAAmC;AAe5B,IAAM,SACX,CAAC,EAAE,UAAU,IAAkB,CAAC,MAChC,CAACC,YAAmB;AAClB,SAAO;AAAA,IACL,YAAQ;AAAA,MACN;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AAEzC,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,eAAe,MAAMA,QAAO,OAAO,OAAO;AAAA,YAC9C,YAAY;AAAA,UACd,CAAC;AAED,cAAI,CAAC,aAAa,WAAW,CAAC,aAAa,MAAM;AAC/C,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SACE,aAAa,WAAW;AAAA,YAC5B,CAAC;AAAA,UACH;AAGA,cAAI,YAAY,aAAa,KAAK;AAClC,cAAI,WAAW;AACb,kBAAM,MAAM,IAAI,IAAI,SAAS;AAC7B,gBAAI,aAAa,IAAI,cAAc,SAAS;AAC5C,wBAAY,IAAI,SAAS;AAAA,UAC3B;AAEA,iBAAO,IAAI,KAAK;AAAA,YACd,KAAK;AAAA,YACL,UAAU;AAAA,UACZ,CAAC;AAAA,QACH,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,gCAAgC,EAAE,OAAO;AAAA,YAC3C;AAAA,UACF;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC7EF,IAAAC,cAA4C;AAC5C,IAAAC,kBAAmC;AACnC,iBAAkB;AASlB,IAAM,mBAAmB,aAAE,OAAO;AAAA,EAChC,QAAQ,aAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,MAAM,aAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,iBAAiB,aAAE,KAAK,CAAC,WAAW,aAAa,QAAQ,CAAC,EAAE,SAAS;AACvE,CAAC;AAED,IAAM,eAAe,aAAE,OAAO;AAAA,EAC5B,QAAQ,aAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,WAAW,aAAE,QAAQ,EAAE,SAAS;AAClC,CAAC;AAUM,IAAM,gBACX,CAAC,SAA8B,CAAC,MAChC,CAACC,YAAmB;AAClB,SAAO;AAAA,IACL,qBAAiB;AAAA,MACf;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AAEzC,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,eAAe,MAAMA,QAAO,cAAc,IAAI,MAAM;AAE1D,cAAI,CAAC,aAAa,SAAS;AACzB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SACE,aAAa,WAAW;AAAA,YAC5B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,aAAa,QAAQ,IAAI;AAAA,QAC3C,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,mCAAmC,EAAE,OAAO;AAAA,YAC9C;AAAA,UACF;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IAEA,gBAAY;AAAA,MACV;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AAEzC,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAGA,YAAI,SAAS,IAAI,KAAK;AACtB,YAAI,IAAI,KAAK,QAAQ,CAAC,QAAQ;AAC5B,gBAAM,OAAO,OAAO,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAAK,IAAI;AAC/D,cAAI,CAAC,MAAM;AACT,kBAAM,IAAI,qBAAS,eAAe;AAAA,cAChC,SAAS,mBAAmB,IAAI,KAAK,IAAI;AAAA,YAC3C,CAAC;AAAA,UACH;AACA,mBAAS,KAAK;AAAA,QAChB;AAEA,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,eAAe;AAAA,YAChC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AAEF,gBAAM,aAAa,MAAMA,QAAO,cAAc,IAAI,MAAM;AAExD,cAAI,CAAC,WAAW,WAAW,CAAC,WAAW,MAAM;AAC3C,kBAAM,IAAI,qBAAS,eAAe;AAAA,cAChC,SAAS;AAAA,YACX,CAAC;AAAA,UACH;AAEA,gBAAM,SAAS,MAAMA,QAAO,cAAc,WAAW;AAAA,YACnD,gBAAgB,WAAW,KAAK;AAAA,YAChC;AAAA,YACA,iBAAiB,IAAI,KAAK;AAAA,UAC5B,CAAC;AAED,cAAI,CAAC,OAAO,SAAS;AACnB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SAAS,OAAO,WAAW;AAAA,YAC7B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,OAAO,QAAQ,IAAI;AAAA,QACrC,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,8BAA8B,EAAE,OAAO;AAAA,YACzC;AAAA,UACF;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IAEA,wBAAoB;AAAA,MAClB;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,MAAM,aAAa,SAAS;AAAA,QAC5B,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AAEzC,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AAEF,gBAAM,aAAa,MAAMA,QAAO,cAAc,IAAI,MAAM;AAExD,cAAI,CAAC,WAAW,WAAW,CAAC,WAAW,MAAM;AAC3C,kBAAM,IAAI,qBAAS,eAAe;AAAA,cAChC,SAAS;AAAA,YACX,CAAC;AAAA,UACH;AAEA,gBAAM,SAAS,MAAMA,QAAO,cAAc,OAAO;AAAA,YAC/C,gBAAgB,WAAW,KAAK;AAAA,YAChC,QAAQ,IAAI,MAAM;AAAA,YAClB,WAAW,IAAI,MAAM;AAAA,UACvB,CAAC;AAED,cAAI,CAAC,OAAO,SAAS;AACnB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SAAS,OAAO,WAAW;AAAA,YAC7B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,OAAO,QAAQ,IAAI;AAAA,QACrC,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,sCAAsC,EAAE,OAAO;AAAA,YACjD;AAAA,UACF;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AClNF,IAAAC,cAA4C;AAC5C,IAAAC,kBAAmC;AAa5B,IAAM,WACX,CAAC,UAA0B,CAAC,MAC5B,CAACC,YAAmB;AAClB,SAAO;AAAA,IACL,kBAAc;AAAA,MACZ;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AAEzC,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,SAAS,MAAMA,QAAO,SAAS,KAAK,MAAM;AAEhD,cAAI,CAAC,OAAO,SAAS;AACnB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SAAS,OAAO,WAAW;AAAA,YAC7B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,OAAO,QAAQ,IAAI;AAAA,QACrC,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,gCAAgC,EAAE,OAAO;AAAA,YAC3C;AAAA,UACF;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IAEA,gBAAY;AAAA,MACV;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AACzC,cAAM,OAAO,IAAI,QAAQ;AAEzB,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI,CAAC,MAAM;AACT,gBAAM,IAAI,qBAAS,eAAe;AAAA,YAChC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,SAAS,MAAMA,QAAO,SAAS,IAAI;AAAA,YACvC,YAAY;AAAA,YACZ;AAAA,UACF,CAAC;AAED,cAAI,CAAC,OAAO,SAAS;AACnB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SAAS,OAAO,WAAW;AAAA,YAC7B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,OAAO,QAAQ,IAAI;AAAA,QACrC,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,8BAA8B,EAAE,OAAO;AAAA,YACzC;AAAA,UACF;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IAEA,kBAAc;AAAA,MACZ;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AACzC,cAAM,OAAO,IAAI,QAAQ;AAEzB,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI,CAAC,MAAM;AACT,gBAAM,IAAI,qBAAS,eAAe;AAAA,YAChC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,SAAS,MAAMA,QAAO,SAAS,MAAM;AAAA,YACzC,YAAY;AAAA,YACZ;AAAA,UACF,CAAC;AAED,cAAI,CAAC,OAAO,SAAS;AACnB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SAAS,OAAO,WAAW;AAAA,YAC7B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,OAAO,QAAQ,IAAI;AAAA,QACrC,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,gCAAgC,EAAE,OAAO;AAAA,YAC3C;AAAA,UACF;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IAEA,mBAAe;AAAA,MACb;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AACzC,cAAM,OAAO,IAAI,QAAQ;AAEzB,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI,CAAC,MAAM;AACT,gBAAM,IAAI,qBAAS,eAAe;AAAA,YAChC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,SAAS,MAAMA,QAAO,SAAS,OAAO;AAAA,YAC1C,YAAY;AAAA,YACZ;AAAA,UACF,CAAC;AAED,cAAI,CAAC,OAAO,SAAS;AACnB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SAAS,OAAO,WAAW;AAAA,YAC7B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,OAAO,QAAQ,IAAI;AAAA,QACrC,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,iCAAiC,EAAE,OAAO;AAAA,YAC5C;AAAA,UACF;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC5NF,IAAAC,cAA4C;AAC5C,IAAAC,kBAAmC;AACnC,IAAAC,cAAkB;AAIlB,IAAM,mBAAmB,cAAE,OAAO;AAAA,EAChC,SAAS,cAAE,OAAO;AAAA,EAClB,OAAO,cAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,gBAAgB,cAAE,OAAO,EAAE,SAAS;AAAA,EACpC,YAAY,cAAE,OAAO,cAAE,OAAO,GAAG,cAAE,OAAO,CAAC,EAAE,SAAS;AACxD,CAAC;AAQM,IAAM,QACX,CAAC,UAAuB,CAAC,MACzB,CAACC,YAAmB;AAClB,SAAO;AAAA,IACL,gBAAY;AAAA,MACV;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AAEzC,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,SAAS,MAAMA,QAAO,MAAM;AAAA,YAChC;AAAA,cACE,YAAY;AAAA,cACZ,SAAS,IAAI,KAAK;AAAA,cAClB,OAAO,IAAI,KAAK;AAAA,cAChB,gBAAgB,IAAI,KAAK;AAAA,cACzB,YAAY,IAAI,KAAK;AAAA,YACvB;AAAA,YACA,CAAC;AAAA,UACH;AAEA,cAAI,CAAC,OAAO,SAAS;AACnB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SAAS,OAAO,WAAW;AAAA,YAC7B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,OAAO,QAAQ,IAAI;AAAA,QACrC,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,8BAA8B,EAAE,OAAO;AAAA,YACzC;AAAA,UACF;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC5EF,IAAAC,cAA4C;AAC5C,IAAAC,kBAAmC;AACnC,IAAAC,cAAkB;AAIlB,IAAM,sBAAsB,cAAE,OAAO;AAAA,EACnC,UAAU,cAAE,OAAO;AAAA,EACnB,OAAO,cAAE,OAAO,EAAE,IAAI,CAAC;AACzB,CAAC;AAED,IAAM,oBAAoB,cAAE,OAAO;AAAA,EACjC,OAAO,cAAE,OAAO,cAAE,OAAO,GAAG,cAAE,OAAO,CAAC;AACxC,CAAC;AAYM,IAAM,QACX,CAAC,UAAuB,CAAC,MACzB,CAACC,YAAmB;AAClB,SAAO;AAAA,IACL,eAAW;AAAA,MACT;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AAEzC,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,SAAS,MAAMA,QAAO,MAAM,eAAe;AAAA,YAC/C,YAAY;AAAA,UACd,CAAC;AAED,cAAI,CAAC,OAAO,SAAS;AACnB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SAAS,OAAO,WAAW;AAAA,YAC7B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,OAAO,QAAQ,IAAI;AAAA,QACrC,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,6BAA6B,EAAE,OAAO;AAAA,YACxC;AAAA,UACF;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IAEA,cAAU;AAAA,MACR;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AAEzC,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,SAAS,MAAMA,QAAO,MAAM;AAAA,YAChC;AAAA,cACE,YAAY;AAAA,cACZ,UAAU,IAAI,KAAK;AAAA,cACnB,OAAO,IAAI,KAAK;AAAA,YAClB;AAAA,YACA,CAAC;AAAA,UACH;AAEA,cAAI,CAAC,OAAO,SAAS;AACnB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SAAS,OAAO,WAAW;AAAA,YAC7B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,OAAO,QAAQ,IAAI;AAAA,QACrC,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO,MAAM,4BAA4B,EAAE,OAAO,EAAE;AAAA,UAClE;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IAEA,iBAAa;AAAA,MACX;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AAEzC,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,SAAS,MAAMA,QAAO,MAAM;AAAA,YAChC;AAAA,cACE,YAAY;AAAA,cACZ,UAAU,IAAI,KAAK;AAAA,cACnB,OAAO,IAAI,KAAK;AAAA,YAClB;AAAA,YACA,CAAC;AAAA,UACH;AAEA,cAAI,CAAC,OAAO,SAAS;AACnB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SAAS,OAAO,WAAW;AAAA,YAC7B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,OAAO,QAAQ,IAAI;AAAA,QACrC,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,+BAA+B,EAAE,OAAO;AAAA,YAC1C;AAAA,UACF;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IAEA,cAAU;AAAA,MACR;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AAEzC,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,SAAS,MAAMA,QAAO,MAAM;AAAA,YAChC;AAAA,cACE,YAAY;AAAA,cACZ,UAAU,IAAI,KAAK;AAAA,cACnB,OAAO,IAAI,KAAK;AAAA,YAClB;AAAA,YACA,CAAC;AAAA,UACH;AAEA,cAAI,CAAC,OAAO,SAAS;AACnB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SAAS,OAAO,WAAW;AAAA,YAC7B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,OAAO,QAAQ,IAAI;AAAA,QACrC,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO,MAAM,4BAA4B,EAAE,OAAO,EAAE;AAAA,UAClE;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IAEA,iBAAa;AAAA,MACX;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,KAAK,CAAC,6BAAiB;AAAA,MACzB;AAAA,MACA,OAAO,QAAQ;AACb,cAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AAEzC,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,SAAS,MAAMA,QAAO,MAAM;AAAA,YAChC;AAAA,cACE,YAAY;AAAA,cACZ,OAAO,IAAI,KAAK;AAAA,YAClB;AAAA,YACA,CAAC;AAAA,UACH;AAEA,cAAI,CAAC,OAAO,SAAS;AACnB,kBAAM,IAAI,qBAAS,yBAAyB;AAAA,cAC1C,SAAS,OAAO,WAAW;AAAA,YAC7B,CAAC;AAAA,UACH;AAEA,iBAAO,IAAI,KAAK,OAAO,QAAQ,IAAI;AAAA,QACrC,SAAS,GAAY;AACnB,cAAI,aAAa,sBAAU;AACzB,kBAAM;AAAA,UACR;AAEA,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,gCAAgC,EAAE,OAAO;AAAA,YAC3C;AAAA,UACF;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACjRF,IAAAC,cAA6C;AA4C7C,IAAM,oBAAgE;AAAA,EACpE,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,yBAAyB;AAAA,EACzB,wBAAwB;AAC1B;AAkBO,IAAM,WAAW,CAAC,WAA2B,CAACC,YAAmB;AACtE,SAAO;AAAA,IACL,oBAAgB;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,UAAU;AAAA,UACR,UAAU;AAAA,QACZ;AAAA,QACA,cAAc;AAAA,MAChB;AAAA,MACA,OAAO,QAAQ;AACb,YAAI,CAAC,IAAI,SAAS,MAAM;AACtB,gBAAM,IAAI,qBAAS,eAAe;AAAA,YAChC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,cAAM,UAAU,MAAM,IAAI,QAAQ,KAAK;AACvC,cAAM,YAAY,IAAI,QAAQ,QAAQ,IAAI,oBAAoB;AAG9D,cAAM,UAAUA,QAAO,SAAS,eAAe;AAAA,UAC7C;AAAA,UACA;AAAA,UACA,QAAQ,OAAO;AAAA,QACjB,CAAC;AAED,YAAI,CAAC,SAAS;AACZ,cAAI,QAAQ,OAAO,MAAM,2BAA2B;AACpD,gBAAM,IAAI,qBAAS,gBAAgB;AAAA,YACjC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,YAAI;AAEF,gBAAM,aAAa,kBAAkB,QAAQ,KAAK;AAClD,cAAI,YAAY;AACd,kBAAM,UAAU,OAAO,UAAU;AACjC,gBAAI,SAAS;AACX,oBAAM,QAAQ,OAAO;AAAA,YACvB;AAAA,UACF;AAGA,cAAI,OAAO,WAAW;AACpB,kBAAM,OAAO,UAAU,OAAO;AAAA,UAChC;AAEA,iBAAO,IAAI,KAAK,EAAE,UAAU,KAAK,CAAC;AAAA,QACpC,SAAS,GAAY;AACnB,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,iCAAiC,EAAE,OAAO;AAAA,YAC5C;AAAA,UACF,OAAO;AACL,gBAAI,QAAQ,OAAO,MAAM,8BAA8B;AAAA,UACzD;AAEA,gBAAM,IAAI,qBAAS,yBAAyB;AAAA,YAC1C,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ARpDO,IAAM,SAAS,CAA0B,YAAe;AAE7D,QAAM,UAAU,QAAQ,IACrB,IAAI,CAAC,QAAQ,IAAI,QAAQ,MAAM,CAAC,EAChC,OAAO,CAAC,KAAK,WAAW;AACvB,WAAO,OAAO,KAAK,MAAM;AACzB,WAAO;AAAA,EACT,GAAG,CAAC,CAAoB;AAE1B,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,WAAW;AAAA,MACT,GAAG;AAAA,IACL;AAAA,IACA,OAAO;AACL,aAAO;AAAA,QACL,SAAS;AAAA,UACP,eAAe;AAAA,YACb,MAAM;AAAA,cACJ,QAAQ;AAAA,gBACN,QAAQ,mBAAmB,OAAO;AAAA,gBAClC,OAAO,kBAAkB,OAAO;AAAA,cAClC;AAAA,cACA,QAAQ;AAAA,gBACN,OAAO,aAAa,OAAO;AAAA,cAC7B;AAAA,cACA,QAAQ;AAAA,gBACN,OAAO,aAAa,OAAO;AAAA,cAC7B;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","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/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"]}