@commet/node 1.6.2 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  <p>TypeScript SDK for Commet billing platform</p>
9
9
 
10
10
  <a href="https://www.npmjs.com/package/@commet/node"><img alt="NPM version" src="https://img.shields.io/npm/v/@commet/node.svg?style=for-the-badge&labelColor=000000"></a>
11
- <a href="https://commet.co/docs/library/quickstart"><img alt="Documentation" src="https://img.shields.io/badge/docs-SDK-blue.svg?style=for-the-badge&labelColor=000000"></a>
11
+ <a href="https://commet.co/docs"><img alt="Documentation" src="https://img.shields.io/badge/docs-SDK-blue.svg?style=for-the-badge&labelColor=000000"></a>
12
12
  </div>
13
13
 
14
14
  <br/>
@@ -81,7 +81,7 @@ This generates type-safe autocomplete for your plan codes, feature codes, and se
81
81
 
82
82
  ## Documentation
83
83
 
84
- Visit [commet.co/docs/library/quickstart](https://commet.co/docs/library/quickstart) for:
84
+ Visit [commet.co/docs](https://commet.co/docs) for:
85
85
 
86
86
  - Complete API reference
87
87
  - Advanced usage examples
@@ -90,8 +90,8 @@ Visit [commet.co/docs/library/quickstart](https://commet.co/docs/library/quickst
90
90
 
91
91
  ## Resources
92
92
 
93
- - [CLI Documentation](https://commet.co/docs/library/cli/overview)
94
- - [SDK Reference](https://commet.co/docs/library/quickstart)
93
+ - [CLI Documentation](https://commet.co/docs)
94
+ - [SDK Reference](https://commet.co/docs)
95
95
  - [GitHub](https://github.com/commet-labs/commet)
96
96
  - [Issues](https://github.com/commet-labs/commet/issues)
97
97
 
package/dist/index.d.mts CHANGED
@@ -659,49 +659,31 @@ interface BatchResult$1<T> {
659
659
  data: TrackParams;
660
660
  }>;
661
661
  }
662
- interface TrackParams {
662
+ interface TrackBaseParams {
663
663
  feature: GeneratedFeatureCode;
664
664
  customerId?: CustomerID;
665
665
  externalId?: string;
666
666
  idempotencyKey?: string;
667
- value?: number;
668
667
  timestamp?: string;
669
668
  properties?: Record<string, string>;
670
669
  }
671
- /**
672
- * Usage resource - Track consumption events for usage-based billing
673
- */
670
+ interface TrackUsageParams extends TrackBaseParams {
671
+ value?: number;
672
+ model?: never;
673
+ }
674
+ interface TrackModelTokensParams extends TrackBaseParams {
675
+ model: string;
676
+ inputTokens: number;
677
+ outputTokens: number;
678
+ cacheReadTokens?: number;
679
+ cacheWriteTokens?: number;
680
+ value?: never;
681
+ }
682
+ type TrackParams = TrackUsageParams | TrackModelTokensParams;
674
683
  declare class UsageResource {
675
684
  private httpClient;
676
685
  constructor(httpClient: CommetHTTPClient);
677
- /**
678
- * Track a usage event
679
- *
680
- * @example
681
- * ```typescript
682
- * await commet.usage.track({
683
- * externalId: 'user_123',
684
- * feature: 'api_call',
685
- * value: 1,
686
- * idempotencyKey: `evt_${requestId}`,
687
- * properties: { endpoint: '/users', method: 'GET' }
688
- * });
689
- * ```
690
- */
691
686
  track(params: TrackParams, options?: RequestOptions): Promise<ApiResponse<UsageEvent>>;
692
- /**
693
- * Track multiple usage events in a batch
694
- *
695
- * @example
696
- * ```typescript
697
- * await commet.usage.trackBatch({
698
- * events: [
699
- * { externalId: 'user_123', feature: 'api_call', value: 1, idempotencyKey: 'evt_1' },
700
- * { externalId: 'user_456', feature: 'api_call', value: 5, idempotencyKey: 'evt_2' }
701
- * ]
702
- * });
703
- * ```
704
- */
705
687
  trackBatch(params: {
706
688
  events: TrackParams[];
707
689
  }, options?: RequestOptions): Promise<ApiResponse<BatchResult$1<UsageEvent>>>;
@@ -1049,4 +1031,4 @@ declare function isProduction(environment: Environment): boolean;
1049
1031
  * Commet SDK - Billing and usage tracking for SaaS
1050
1032
  */
1051
1033
 
1052
- export { type ActiveSubscription, type AddParams as AddSeatsParams, type ApiResponse, type BillingInterval, type CanUseFeatureParams, type CanUseResult, type CancelParams, type CheckFeatureParams, type CheckResult, Commet, CommetAPIError, type CommetConfig, CommetError, type CommetGeneratedTypes, CommetValidationError, type CreateParams as CreateCustomerParams, type CreateSubscriptionParams, type CreatedSubscription, type CreditPack, type Currency, type Customer, type CustomerAddress, CustomerContext, type CustomerID, type BatchResult as CustomersBatchResult, type Environment, type EventID, type FeatureAccess, type FeatureSummary, type FeatureType, type GeneratedFeatureCode, type GeneratedPlanCode, type GeneratedSeatType, type GetAllBalancesParams, type GetBalanceParams, type GetFeatureParams, type GetUrlParams, type ListCustomersParams, type ListPlansParams, type PaginatedList, type PaginatedResponse, type Plan, type PlanDetail, type PlanFeature, type PlanID, type PlanPrice, type PortalAccess, type RemoveParams as RemoveSeatsParams, type RequestOptions, type SeatBalance, type SeatEvent, type SetAllParams as SetAllSeatsParams, type SetParams as SetSeatsParams, type Subscription, type SubscriptionStatus, type TrackParams, type UpdateParams as UpdateCustomerParams, type BatchResult$1 as UsageBatchResult, type UsageEvent, type UsageEventProperty, type WebhookData, type WebhookEvent, type WebhookPayload, Webhooks, Commet as default, isProduction, isSandbox };
1034
+ export { type ActiveSubscription, type AddParams as AddSeatsParams, type ApiResponse, type BillingInterval, type CanUseFeatureParams, type CanUseResult, type CancelParams, type CheckFeatureParams, type CheckResult, Commet, CommetAPIError, type CommetConfig, CommetError, type CommetGeneratedTypes, CommetValidationError, type CreateParams as CreateCustomerParams, type CreateSubscriptionParams, type CreatedSubscription, type CreditPack, type Currency, type Customer, type CustomerAddress, CustomerContext, type CustomerID, type BatchResult as CustomersBatchResult, type Environment, type EventID, type FeatureAccess, type FeatureSummary, type FeatureType, type GeneratedFeatureCode, type GeneratedPlanCode, type GeneratedSeatType, type GetAllBalancesParams, type GetBalanceParams, type GetFeatureParams, type GetUrlParams, type ListCustomersParams, type ListPlansParams, type PaginatedList, type PaginatedResponse, type Plan, type PlanDetail, type PlanFeature, type PlanID, type PlanPrice, type PortalAccess, type RemoveParams as RemoveSeatsParams, type RequestOptions, type SeatBalance, type SeatEvent, type SetAllParams as SetAllSeatsParams, type SetParams as SetSeatsParams, type Subscription, type SubscriptionStatus, type TrackModelTokensParams, type TrackParams, type TrackUsageParams, type UpdateParams as UpdateCustomerParams, type BatchResult$1 as UsageBatchResult, type UsageEvent, type UsageEventProperty, type WebhookData, type WebhookEvent, type WebhookPayload, Webhooks, Commet as default, isProduction, isSandbox };
package/dist/index.d.ts CHANGED
@@ -659,49 +659,31 @@ interface BatchResult$1<T> {
659
659
  data: TrackParams;
660
660
  }>;
661
661
  }
662
- interface TrackParams {
662
+ interface TrackBaseParams {
663
663
  feature: GeneratedFeatureCode;
664
664
  customerId?: CustomerID;
665
665
  externalId?: string;
666
666
  idempotencyKey?: string;
667
- value?: number;
668
667
  timestamp?: string;
669
668
  properties?: Record<string, string>;
670
669
  }
671
- /**
672
- * Usage resource - Track consumption events for usage-based billing
673
- */
670
+ interface TrackUsageParams extends TrackBaseParams {
671
+ value?: number;
672
+ model?: never;
673
+ }
674
+ interface TrackModelTokensParams extends TrackBaseParams {
675
+ model: string;
676
+ inputTokens: number;
677
+ outputTokens: number;
678
+ cacheReadTokens?: number;
679
+ cacheWriteTokens?: number;
680
+ value?: never;
681
+ }
682
+ type TrackParams = TrackUsageParams | TrackModelTokensParams;
674
683
  declare class UsageResource {
675
684
  private httpClient;
676
685
  constructor(httpClient: CommetHTTPClient);
677
- /**
678
- * Track a usage event
679
- *
680
- * @example
681
- * ```typescript
682
- * await commet.usage.track({
683
- * externalId: 'user_123',
684
- * feature: 'api_call',
685
- * value: 1,
686
- * idempotencyKey: `evt_${requestId}`,
687
- * properties: { endpoint: '/users', method: 'GET' }
688
- * });
689
- * ```
690
- */
691
686
  track(params: TrackParams, options?: RequestOptions): Promise<ApiResponse<UsageEvent>>;
692
- /**
693
- * Track multiple usage events in a batch
694
- *
695
- * @example
696
- * ```typescript
697
- * await commet.usage.trackBatch({
698
- * events: [
699
- * { externalId: 'user_123', feature: 'api_call', value: 1, idempotencyKey: 'evt_1' },
700
- * { externalId: 'user_456', feature: 'api_call', value: 5, idempotencyKey: 'evt_2' }
701
- * ]
702
- * });
703
- * ```
704
- */
705
687
  trackBatch(params: {
706
688
  events: TrackParams[];
707
689
  }, options?: RequestOptions): Promise<ApiResponse<BatchResult$1<UsageEvent>>>;
@@ -1049,4 +1031,4 @@ declare function isProduction(environment: Environment): boolean;
1049
1031
  * Commet SDK - Billing and usage tracking for SaaS
1050
1032
  */
1051
1033
 
1052
- export { type ActiveSubscription, type AddParams as AddSeatsParams, type ApiResponse, type BillingInterval, type CanUseFeatureParams, type CanUseResult, type CancelParams, type CheckFeatureParams, type CheckResult, Commet, CommetAPIError, type CommetConfig, CommetError, type CommetGeneratedTypes, CommetValidationError, type CreateParams as CreateCustomerParams, type CreateSubscriptionParams, type CreatedSubscription, type CreditPack, type Currency, type Customer, type CustomerAddress, CustomerContext, type CustomerID, type BatchResult as CustomersBatchResult, type Environment, type EventID, type FeatureAccess, type FeatureSummary, type FeatureType, type GeneratedFeatureCode, type GeneratedPlanCode, type GeneratedSeatType, type GetAllBalancesParams, type GetBalanceParams, type GetFeatureParams, type GetUrlParams, type ListCustomersParams, type ListPlansParams, type PaginatedList, type PaginatedResponse, type Plan, type PlanDetail, type PlanFeature, type PlanID, type PlanPrice, type PortalAccess, type RemoveParams as RemoveSeatsParams, type RequestOptions, type SeatBalance, type SeatEvent, type SetAllParams as SetAllSeatsParams, type SetParams as SetSeatsParams, type Subscription, type SubscriptionStatus, type TrackParams, type UpdateParams as UpdateCustomerParams, type BatchResult$1 as UsageBatchResult, type UsageEvent, type UsageEventProperty, type WebhookData, type WebhookEvent, type WebhookPayload, Webhooks, Commet as default, isProduction, isSandbox };
1034
+ export { type ActiveSubscription, type AddParams as AddSeatsParams, type ApiResponse, type BillingInterval, type CanUseFeatureParams, type CanUseResult, type CancelParams, type CheckFeatureParams, type CheckResult, Commet, CommetAPIError, type CommetConfig, CommetError, type CommetGeneratedTypes, CommetValidationError, type CreateParams as CreateCustomerParams, type CreateSubscriptionParams, type CreatedSubscription, type CreditPack, type Currency, type Customer, type CustomerAddress, CustomerContext, type CustomerID, type BatchResult as CustomersBatchResult, type Environment, type EventID, type FeatureAccess, type FeatureSummary, type FeatureType, type GeneratedFeatureCode, type GeneratedPlanCode, type GeneratedSeatType, type GetAllBalancesParams, type GetBalanceParams, type GetFeatureParams, type GetUrlParams, type ListCustomersParams, type ListPlansParams, type PaginatedList, type PaginatedResponse, type Plan, type PlanDetail, type PlanFeature, type PlanID, type PlanPrice, type PortalAccess, type RemoveParams as RemoveSeatsParams, type RequestOptions, type SeatBalance, type SeatEvent, type SetAllParams as SetAllSeatsParams, type SetParams as SetSeatsParams, type Subscription, type SubscriptionStatus, type TrackModelTokensParams, type TrackParams, type TrackUsageParams, type UpdateParams as UpdateCustomerParams, type BatchResult$1 as UsageBatchResult, type UsageEvent, type UsageEventProperty, type WebhookData, type WebhookEvent, type WebhookPayload, Webhooks, Commet as default, isProduction, isSandbox };
package/dist/index.js CHANGED
@@ -527,61 +527,61 @@ var UsageResource = class {
527
527
  constructor(httpClient) {
528
528
  this.httpClient = httpClient;
529
529
  }
530
- /**
531
- * Track a usage event
532
- *
533
- * @example
534
- * ```typescript
535
- * await commet.usage.track({
536
- * externalId: 'user_123',
537
- * feature: 'api_call',
538
- * value: 1,
539
- * idempotencyKey: `evt_${requestId}`,
540
- * properties: { endpoint: '/users', method: 'GET' }
541
- * });
542
- * ```
543
- */
544
530
  async track(params, options) {
545
531
  const eventData = {
546
532
  feature: params.feature,
547
533
  customerId: params.customerId,
548
534
  externalId: params.externalId,
549
535
  idempotencyKey: params.idempotencyKey,
550
- value: params.value,
551
536
  timestamp: params.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
552
537
  properties: params.properties ? Object.entries(params.properties).map(([property, value]) => ({
553
538
  property,
554
539
  value
555
540
  })) : void 0
556
541
  };
542
+ if ("model" in params && params.model) {
543
+ eventData.model = params.model;
544
+ eventData.inputTokens = params.inputTokens;
545
+ eventData.outputTokens = params.outputTokens;
546
+ if (params.cacheReadTokens) {
547
+ eventData.cacheReadTokens = params.cacheReadTokens;
548
+ }
549
+ if (params.cacheWriteTokens) {
550
+ eventData.cacheWriteTokens = params.cacheWriteTokens;
551
+ }
552
+ } else {
553
+ eventData.value = params.value;
554
+ }
557
555
  return this.httpClient.post("/usage/events", eventData, options);
558
556
  }
559
- /**
560
- * Track multiple usage events in a batch
561
- *
562
- * @example
563
- * ```typescript
564
- * await commet.usage.trackBatch({
565
- * events: [
566
- * { externalId: 'user_123', feature: 'api_call', value: 1, idempotencyKey: 'evt_1' },
567
- * { externalId: 'user_456', feature: 'api_call', value: 5, idempotencyKey: 'evt_2' }
568
- * ]
569
- * });
570
- * ```
571
- */
572
557
  async trackBatch(params, options) {
573
- const events = params.events.map((event) => ({
574
- feature: event.feature,
575
- customerId: event.customerId,
576
- externalId: event.externalId,
577
- idempotencyKey: event.idempotencyKey,
578
- value: event.value,
579
- timestamp: event.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
580
- properties: event.properties ? Object.entries(event.properties).map(([property, value]) => ({
581
- property,
582
- value
583
- })) : void 0
584
- }));
558
+ const events = params.events.map((event) => {
559
+ const eventData = {
560
+ feature: event.feature,
561
+ customerId: event.customerId,
562
+ externalId: event.externalId,
563
+ idempotencyKey: event.idempotencyKey,
564
+ timestamp: event.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
565
+ properties: event.properties ? Object.entries(event.properties).map(([property, value]) => ({
566
+ property,
567
+ value
568
+ })) : void 0
569
+ };
570
+ if ("model" in event && event.model) {
571
+ eventData.model = event.model;
572
+ eventData.inputTokens = event.inputTokens;
573
+ eventData.outputTokens = event.outputTokens;
574
+ if (event.cacheReadTokens) {
575
+ eventData.cacheReadTokens = event.cacheReadTokens;
576
+ }
577
+ if (event.cacheWriteTokens) {
578
+ eventData.cacheWriteTokens = event.cacheWriteTokens;
579
+ }
580
+ } else {
581
+ eventData.value = event.value;
582
+ }
583
+ return eventData;
584
+ });
585
585
  return this.httpClient.post("/usage/events/batch", { events }, options);
586
586
  }
587
587
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/customer.ts","../src/resources/credit-packs.ts","../src/resources/customers.ts","../src/resources/features.ts","../src/resources/plans.ts","../src/resources/portal.ts","../src/resources/seats.ts","../src/resources/subscriptions.ts","../src/resources/usage.ts","../src/resources/webhooks.ts","../src/types/common.ts","../src/utils/http.ts","../src/client.ts","../src/utils/environment.ts"],"sourcesContent":["/**\n * Commet SDK - Billing and usage tracking for SaaS\n */\nexport { Commet } from \"./client\";\nexport { CustomerContext } from \"./customer\";\n\n// Type exports\nexport type {\n CommetConfig,\n CommetGeneratedTypes,\n GeneratedSeatType,\n GeneratedPlanCode,\n GeneratedFeatureCode,\n Environment,\n ApiResponse,\n PaginatedResponse,\n PaginatedList,\n Currency,\n CustomerID,\n EventID,\n RequestOptions,\n} from \"./types/common\";\n\n// Error exports\nexport {\n CommetError,\n CommetAPIError,\n CommetValidationError,\n} from \"./types/common\";\n\n// Customers\nexport type {\n Customer,\n CustomerAddress,\n CreateParams as CreateCustomerParams,\n UpdateParams as UpdateCustomerParams,\n ListCustomersParams,\n BatchResult as CustomersBatchResult,\n} from \"./resources/customers\";\n\n// Usage\nexport type {\n UsageEvent,\n UsageEventProperty,\n TrackParams,\n BatchResult as UsageBatchResult,\n} from \"./resources/usage\";\n\n// Seats\nexport type {\n SeatEvent,\n SeatBalance,\n AddParams as AddSeatsParams,\n RemoveParams as RemoveSeatsParams,\n SetParams as SetSeatsParams,\n SetAllParams as SetAllSeatsParams,\n GetBalanceParams,\n GetAllBalancesParams,\n} from \"./resources/seats\";\n\n// Credit Packs\nexport type { CreditPack } from \"./resources/credit-packs\";\n\n// Plans\nexport type {\n Plan,\n PlanDetail,\n PlanPrice,\n PlanFeature,\n PlanID,\n BillingInterval,\n FeatureType,\n ListPlansParams,\n} from \"./resources/plans\";\n\n// Subscriptions\nexport type {\n CreatedSubscription,\n Subscription,\n ActiveSubscription,\n SubscriptionStatus,\n FeatureSummary,\n CreateSubscriptionParams,\n CancelParams,\n} from \"./resources/subscriptions\";\n\n// Portal\nexport type { PortalAccess, GetUrlParams } from \"./resources/portal\";\n\n// Features\nexport type {\n FeatureAccess,\n CanUseResult,\n CheckResult,\n GetFeatureParams,\n CheckFeatureParams,\n CanUseFeatureParams,\n} from \"./resources/features\";\n\n// Webhooks\nexport { Webhooks } from \"./resources/webhooks\";\nexport type {\n WebhookPayload,\n WebhookData,\n WebhookEvent,\n} from \"./resources/webhooks\";\n\n// Utility exports\nexport { isSandbox, isProduction } from \"./utils/environment\";\n\n// Default export\nimport { Commet } from \"./client\";\nexport default Commet;\n","import type { FeaturesResource } from \"./resources/features\";\nimport type { PortalResource } from \"./resources/portal\";\nimport type { SeatsResource } from \"./resources/seats\";\nimport type { SubscriptionsResource } from \"./resources/subscriptions\";\nimport type { UsageResource } from \"./resources/usage\";\nimport type { RequestOptions } from \"./types/common\";\n\n/**\n * Customer-scoped API context\n *\n * Provides a cleaner API where you don't have to pass externalId\n * on every call. All operations are scoped to a specific customer.\n *\n * @example\n * ```typescript\n * const customer = commet.customer(\"user_123\");\n *\n * // All operations are now scoped to this customer\n * const seats = await customer.features.get(\"team_members\");\n * await customer.seats.add(\"member\");\n * await customer.usage.track(\"api_call\");\n * ```\n */\nexport class CustomerContext {\n private readonly externalId: string;\n private readonly featuresResource: FeaturesResource;\n private readonly seatsResource: SeatsResource;\n private readonly usageResource: UsageResource;\n private readonly subscriptionsResource: SubscriptionsResource;\n private readonly portalResource: PortalResource;\n\n constructor(\n externalId: string,\n resources: {\n features: FeaturesResource;\n seats: SeatsResource;\n usage: UsageResource;\n subscriptions: SubscriptionsResource;\n portal: PortalResource;\n },\n ) {\n this.externalId = externalId;\n this.featuresResource = resources.features;\n this.seatsResource = resources.seats;\n this.usageResource = resources.usage;\n this.subscriptionsResource = resources.subscriptions;\n this.portalResource = resources.portal;\n }\n\n /**\n * Feature access methods - delegates to FeaturesResource\n */\n features = {\n get: (code: string, options?: RequestOptions) =>\n this.featuresResource.get({ code, externalId: this.externalId }, options),\n\n check: (code: string, options?: RequestOptions) =>\n this.featuresResource.check(\n { code, externalId: this.externalId },\n options,\n ),\n\n canUse: (code: string, options?: RequestOptions) =>\n this.featuresResource.canUse(\n { code, externalId: this.externalId },\n options,\n ),\n\n list: (options?: RequestOptions) =>\n this.featuresResource.list(this.externalId, options),\n };\n\n /**\n * Seat management methods - delegates to SeatsResource\n */\n seats = {\n add: (seatType: string, count = 1, options?: RequestOptions) =>\n this.seatsResource.add(\n { externalId: this.externalId, seatType, count },\n options,\n ),\n\n remove: (seatType: string, count = 1, options?: RequestOptions) =>\n this.seatsResource.remove(\n { externalId: this.externalId, seatType, count },\n options,\n ),\n\n set: (seatType: string, count: number, options?: RequestOptions) =>\n this.seatsResource.set(\n { externalId: this.externalId, seatType, count },\n options,\n ),\n\n getBalance: (seatType: string) =>\n this.seatsResource.getBalance({ externalId: this.externalId, seatType }),\n };\n\n /**\n * Usage tracking methods - delegates to UsageResource\n */\n usage = {\n track: (\n feature: string,\n value?: number,\n properties?: Record<string, string>,\n options?: RequestOptions,\n ) =>\n this.usageResource.track(\n { externalId: this.externalId, feature, value, properties },\n options,\n ),\n };\n\n /**\n * Subscription methods - delegates to SubscriptionsResource\n */\n subscription = {\n get: () => this.subscriptionsResource.get(this.externalId),\n };\n\n /**\n * Portal methods - delegates to PortalResource\n */\n portal = {\n getUrl: (options?: RequestOptions) =>\n this.portalResource.getUrl({ externalId: this.externalId }, options),\n };\n}\n","import type { ApiResponse } from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface CreditPack {\n id: string;\n name: string;\n description: string | null;\n credits: number;\n price: number;\n currency: string;\n}\n\n/**\n * Credit Packs resource for listing available credit packs\n */\nexport class CreditPacksResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * List all active credit packs\n *\n * @example\n * ```typescript\n * const packs = await commet.creditPacks.list();\n * console.log(packs.data); // [{ id: \"cp_xxx\", name: \"100 Credits\", ... }]\n * ```\n */\n async list(): Promise<ApiResponse<CreditPack[]>> {\n return this.httpClient.get(\"/credit-packs\");\n }\n}\n","import type {\n ApiResponse,\n ListParams as BaseListParams,\n CustomerID,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface Customer {\n id: CustomerID;\n organizationId: string;\n externalId?: string;\n fullName?: string;\n domain?: string;\n website?: string;\n billingEmail: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CustomerAddress {\n line1: string;\n line2?: string;\n city: string;\n state?: string;\n postalCode: string;\n country: string; // ISO-2\n}\n\nexport interface CreateParams {\n email: string; // billingEmail - the only required field\n externalId?: string;\n fullName?: string;\n domain?: string;\n website?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n metadata?: Record<string, unknown>;\n address?: CustomerAddress;\n}\n\nexport interface UpdateParams {\n customerId: CustomerID;\n externalId?: string;\n email?: string;\n fullName?: string;\n domain?: string;\n website?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ListCustomersParams extends BaseListParams {\n externalId?: string;\n isActive?: boolean;\n search?: string;\n}\n\nexport interface BatchResult {\n successful: Customer[];\n failed: Array<{\n index: number;\n error: string;\n data: CreateParams;\n }>;\n}\n\n/**\n * Customers resource - Manage your customers\n */\nexport class CustomersResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Create a customer (idempotent with externalId)\n */\n async create(\n params: CreateParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.post(\n \"/customers\",\n {\n billingEmail: params.email,\n externalId: params.externalId,\n fullName: params.fullName,\n domain: params.domain,\n website: params.website,\n timezone: params.timezone,\n language: params.language,\n industry: params.industry,\n metadata: params.metadata,\n address: params.address,\n },\n options,\n );\n }\n\n /**\n * Create multiple customers in batch\n */\n async createBatch(\n params: { customers: CreateParams[] },\n options?: RequestOptions,\n ): Promise<ApiResponse<BatchResult>> {\n const customers = params.customers.map((c) => ({\n billingEmail: c.email,\n externalId: c.externalId,\n fullName: c.fullName,\n domain: c.domain,\n website: c.website,\n timezone: c.timezone,\n language: c.language,\n industry: c.industry,\n metadata: c.metadata,\n address: c.address,\n }));\n return this.httpClient.post(\"/customers/batch\", { customers }, options);\n }\n\n /**\n * Get a customer by ID\n */\n async get(customerId: CustomerID): Promise<ApiResponse<Customer>> {\n return this.httpClient.get(`/customers/${customerId}`);\n }\n\n /**\n * Update a customer\n */\n async update(\n params: UpdateParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(\n `/customers/${params.customerId}`,\n {\n billingEmail: params.email,\n externalId: params.externalId,\n fullName: params.fullName,\n domain: params.domain,\n website: params.website,\n timezone: params.timezone,\n language: params.language,\n industry: params.industry,\n metadata: params.metadata,\n },\n options,\n );\n }\n\n /**\n * List customers with optional filters\n */\n async list(params?: ListCustomersParams): Promise<ApiResponse<Customer[]>> {\n return this.httpClient.get(\"/customers\", params as Record<string, unknown>);\n }\n\n /**\n * Archive a customer\n */\n async archive(\n customerId: CustomerID,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(\n `/customers/${customerId}`,\n { isActive: false },\n options,\n );\n }\n}\n","import type {\n ApiResponse,\n GeneratedFeatureCode,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface FeatureParams {\n externalId: string;\n code: GeneratedFeatureCode;\n}\n\nexport type GetFeatureParams = FeatureParams;\nexport type CheckFeatureParams = FeatureParams;\nexport type CanUseFeatureParams = FeatureParams;\n\nexport interface FeatureAccess {\n code: string;\n name: string;\n type: \"boolean\" | \"metered\" | \"seats\";\n allowed: boolean;\n // For boolean features\n enabled?: boolean;\n // For metered/seats features\n current?: number;\n included?: number;\n remaining?: number;\n overage?: number;\n overageUnitPrice?: number;\n unlimited?: boolean;\n overageEnabled?: boolean;\n}\n\nexport interface CanUseResult {\n allowed: boolean;\n willBeCharged: boolean;\n reason?: string;\n}\n\nexport interface CheckResult {\n allowed: boolean;\n}\n\n/**\n * Features resource for checking feature access and usage\n *\n * Provides a clean API to check if a customer can use a feature\n * without having to manually parse subscription data.\n */\nexport class FeaturesResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Get detailed feature access/usage for a customer\n *\n * @example\n * ```typescript\n * const seats = await commet.features.get({ code: \"team_members\", externalId: \"user_123\" });\n * console.log(seats.current, seats.included, seats.remaining);\n * ```\n */\n async get(\n params: GetFeatureParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<FeatureAccess>> {\n const { code, externalId } = params;\n\n return this.httpClient.get(\n `/features/${code}`,\n { externalId: externalId },\n options,\n );\n }\n\n /**\n * Check if a boolean feature is enabled for a customer\n *\n * @example\n * ```typescript\n * const { allowed } = await commet.features.check({\n * code: \"custom_branding\",\n * externalId: \"user_123\"\n * });\n * if (!allowed) redirect(\"/upgrade\");\n * ```\n */\n async check(\n params: CheckFeatureParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<CheckResult>> {\n const { code, externalId } = params;\n\n const result = await this.httpClient.get<FeatureAccess>(\n `/features/${code}`,\n { externalId: externalId },\n options,\n );\n\n if (!result.success || !result.data) {\n return {\n success: false,\n data: { allowed: false },\n message: result.message,\n };\n }\n\n return {\n success: true,\n data: { allowed: result.data.allowed },\n message: result.message,\n };\n }\n\n /**\n * Check if customer can use one more unit of a feature\n *\n * Returns whether the customer can add one more (allowed)\n * and whether they'll be charged extra (willBeCharged).\n *\n * @example\n * ```typescript\n * const { allowed, willBeCharged } = await commet.features.canUse({\n * code: \"team_members\",\n * externalId: \"user_123\"\n * });\n *\n * if (!allowed) {\n * return { error: \"Upgrade to add more members\" };\n * }\n *\n * if (willBeCharged) {\n * // Show confirmation: \"This will cost $10/month extra\"\n * }\n * ```\n */\n async canUse(\n params: CanUseFeatureParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<CanUseResult>> {\n const { code, externalId } = params;\n\n return this.httpClient.get(\n `/features/${code}`,\n { externalId: externalId, action: \"canUse\" },\n options,\n );\n }\n\n /**\n * List all features for a customer's active subscription\n *\n * @example\n * ```typescript\n * const features = await commet.features.list({ externalId: \"user_123\" });\n * for (const feature of features) {\n * console.log(feature.code, feature.allowed);\n * }\n * ```\n */\n async list(\n externalId: string,\n options?: RequestOptions,\n ): Promise<ApiResponse<FeatureAccess[]>> {\n return this.httpClient.get(\"/features\", { externalId }, options);\n }\n}\n","import type {\n ApiResponse,\n GeneratedPlanCode,\n ListParams,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport type PlanID = `plan_${string}`;\nexport type BillingInterval = \"monthly\" | \"quarterly\" | \"yearly\";\nexport type FeatureType = \"boolean\" | \"metered\" | \"seats\";\n\nexport interface PlanPrice {\n billingInterval: BillingInterval;\n price: number; // in cents\n isDefault: boolean;\n trialDays: number;\n}\n\nexport interface PlanFeature {\n code: string;\n name: string;\n type: FeatureType;\n unitName: string | null;\n enabled?: boolean;\n includedAmount?: number;\n unlimited?: boolean;\n overageEnabled?: boolean;\n overageUnitPrice?: number;\n}\n\nexport interface Plan {\n id: PlanID;\n code: string;\n name: string;\n description: string | null;\n isPublic: boolean;\n isFree: boolean;\n isDefault: boolean;\n sortOrder: number;\n prices: PlanPrice[];\n features: PlanFeature[];\n createdAt: string;\n}\n\nexport interface PlanDetailPrice {\n billingInterval: BillingInterval;\n price: number;\n isDefault: boolean;\n trialDays: number;\n introOffer: {\n enabled: boolean;\n discountType: \"percentage\" | \"amount\" | null;\n discountValue: number | null;\n durationCycles: number | null;\n } | null;\n}\n\nexport interface PlanDetailFeature extends PlanFeature {\n overage: {\n enabled: boolean;\n model: \"per_unit\" | \"tiered\" | null;\n unitPrice: number | null;\n } | null;\n}\n\nexport interface PlanDetail {\n id: PlanID;\n code: string;\n name: string;\n description: string | null;\n isPublic: boolean;\n isDefault: boolean;\n sortOrder: number;\n prices: PlanDetailPrice[];\n features: PlanDetailFeature[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ListPlansParams extends ListParams {\n includePrivate?: boolean;\n}\n\n/**\n * Plans resource for listing available plans\n */\nexport class PlansResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * List all available plans\n *\n * @example\n * ```typescript\n * // List public plans\n * const plans = await commet.plans.list();\n *\n * // Include private plans\n * const allPlans = await commet.plans.list({ includePrivate: true });\n * ```\n */\n async list(params?: ListPlansParams): Promise<ApiResponse<Plan[]>> {\n return this.httpClient.get(\"/plans\", params);\n }\n\n /**\n * Get a specific plan by code\n *\n * @example\n * ```typescript\n * const plan = await commet.plans.get('pro');\n * console.log(plan.data.name); // \"Pro\"\n * console.log(plan.data.prices); // [{ billingInterval: 'monthly', price: 9900 }]\n * ```\n */\n async get(planCode: GeneratedPlanCode): Promise<ApiResponse<PlanDetail>> {\n return this.httpClient.get(`/plans/${planCode}`);\n }\n}\n","import type { ApiResponse, CustomerID, RequestOptions } from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface PortalAccess {\n success: boolean;\n message: string;\n portalUrl: string;\n}\n\ninterface GetUrlByCustomerId {\n customerId: CustomerID;\n email?: never;\n externalId?: never;\n}\n\ninterface GetUrlByExternalId {\n externalId: string;\n email?: never;\n customerId?: never;\n}\n\ninterface GetUrlByEmail {\n email: string;\n customerId?: never;\n externalId?: never;\n}\n\nexport type GetUrlParams =\n | GetUrlByCustomerId\n | GetUrlByExternalId\n | GetUrlByEmail;\n\n/**\n * Portal resource - Generate customer portal access\n */\nexport class PortalResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Get a portal URL\n *\n * @example\n * ```typescript\n * const portal = await commet.portal.getUrl({ externalId: 'user_123' });\n * ```\n */\n async getUrl(\n params: GetUrlParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<PortalAccess>> {\n return this.httpClient.post(\"/portal/request-access\", params, options);\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n GeneratedSeatType,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface SeatEvent {\n id: string;\n organizationId: string;\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n eventType: \"add\" | \"remove\" | \"set\";\n quantity: number;\n previousBalance?: number;\n newBalance: number;\n ts: string;\n createdAt: string;\n}\n\nexport interface SeatBalance {\n current: number;\n asOf: string;\n}\n\nexport interface AddParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface RemoveParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface SetParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface SetAllParams {\n customerId?: CustomerID;\n externalId?: string;\n seats: Record<string, number>;\n}\n\nexport interface GetBalanceParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n}\n\nexport interface GetAllBalancesParams {\n customerId?: CustomerID;\n externalId?: string;\n}\n\n/**\n * Seats resource - Manage seat-based licenses\n */\nexport class SeatsResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Add seats\n *\n * @example\n * ```typescript\n * await commet.seats.add({\n * externalId: 'user_123',\n * seatType: 'editor',\n * count: 5\n * });\n * ```\n */\n async add(\n params: AddParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.post(\"/seats\", params, options);\n }\n\n /**\n * Remove seats\n *\n * @example\n * ```typescript\n * await commet.seats.remove({\n * externalId: 'user_123',\n * seatType: 'editor',\n * count: 2\n * });\n * ```\n */\n async remove(\n params: RemoveParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.delete(\"/seats\", params, options);\n }\n\n /**\n * Set seats to a specific count\n *\n * @example\n * ```typescript\n * await commet.seats.set({\n * externalId: 'user_123',\n * seatType: 'editor',\n * count: 10\n * });\n * ```\n */\n async set(\n params: SetParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.put(\"/seats\", params, options);\n }\n\n /**\n * Set all seat types\n *\n * @example\n * ```typescript\n * await commet.seats.setAll({\n * externalId: 'user_123',\n * seats: { editor: 10, viewer: 50 }\n * });\n * ```\n */\n async setAll(\n params: SetAllParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent[]>> {\n return this.httpClient.put(\"/seats/bulk\", params, options);\n }\n\n /**\n * Get balance for a seat type\n *\n * @example\n * ```typescript\n * const balance = await commet.seats.getBalance({\n * externalId: 'user_123',\n * seatType: 'editor'\n * });\n * ```\n */\n async getBalance(\n params: GetBalanceParams,\n ): Promise<ApiResponse<SeatBalance>> {\n const { customerId, externalId, seatType } = params;\n\n return this.httpClient.get(\"/seats/balance\", {\n customerId: customerId,\n externalId: externalId,\n seatType: seatType,\n });\n }\n\n /**\n * Get all seat balances\n *\n * @example\n * ```typescript\n * const balances = await commet.seats.getAllBalances({\n * externalId: 'user_123'\n * });\n * ```\n */\n async getAllBalances(\n params: GetAllBalancesParams,\n ): Promise<ApiResponse<Record<string, SeatBalance>>> {\n const { customerId, externalId } = params;\n\n return this.httpClient.get(\"/seats/balances\", {\n customerId: customerId,\n externalId: externalId,\n });\n }\n}\n","import type {\n ApiResponse,\n GeneratedPlanCode,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\nimport type { BillingInterval } from \"./plans\";\n\nexport type SubscriptionStatus =\n | \"draft\"\n | \"pending_payment\"\n | \"trialing\"\n | \"active\"\n | \"paused\"\n | \"past_due\"\n | \"canceled\"\n | \"expired\";\n\nexport interface FeatureSummary {\n code: string;\n name: string;\n type: \"boolean\" | \"metered\" | \"seats\";\n enabled?: boolean;\n usage?: {\n current: number;\n included: number;\n overage: number;\n overageUnitPrice?: number;\n };\n}\n\nexport interface ActiveSubscription {\n id: string;\n customerId: string;\n plan: {\n id: string;\n name: string;\n basePrice: number;\n billingInterval: BillingInterval | null;\n };\n name: string;\n description: string | null;\n status: SubscriptionStatus;\n trialEndsAt: string | null;\n currentPeriod: {\n start: string;\n end: string;\n daysRemaining: number;\n };\n features: FeatureSummary[];\n startDate: string;\n endDate: string | null;\n billingDayOfMonth: number;\n nextBillingDate: string;\n checkoutUrl: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreatedSubscription {\n id: string;\n customerId: string;\n externalId: string;\n planId: string;\n planName: string;\n name: string;\n status: SubscriptionStatus;\n billingInterval: BillingInterval | null;\n trialEndsAt: string | null;\n startDate: string;\n endDate: string | null;\n currentPeriodStart: string | null;\n currentPeriodEnd: string | null;\n billingDayOfMonth: number;\n checkoutUrl: string | null;\n createdAt: string;\n updatedAt: string;\n introOfferEndsAt: string | null;\n introOfferDiscountType: \"percentage\" | \"amount\" | null;\n introOfferDiscountValue: number | null;\n}\n\nexport interface Subscription {\n id: string;\n customerId: string;\n planId: string;\n planName: string;\n name: string;\n description?: string;\n status: SubscriptionStatus;\n billingInterval: BillingInterval;\n trialEndsAt?: string;\n startDate: string;\n endDate?: string;\n currentPeriodStart?: string;\n currentPeriodEnd?: string;\n billingDayOfMonth: number;\n checkoutUrl?: string;\n createdAt: string;\n updatedAt: string;\n}\n\n// Customer identifier: mutually exclusive customerId or externalId\ntype CustomerIdentifier =\n | { customerId: string; externalId?: never }\n | { customerId?: never; externalId: string };\n\n// Plan identifier: use planCode (with autocomplete) or planId (legacy)\ntype PlanIdentifier =\n | { planCode: GeneratedPlanCode; planId?: never }\n | { planCode?: never; planId: string };\n\nexport type CreateSubscriptionParams = CustomerIdentifier &\n PlanIdentifier & {\n billingInterval?: BillingInterval;\n initialSeats?: Record<string, number>;\n skipTrial?: boolean;\n name?: string;\n startDate?: string;\n successUrl?: string;\n };\n\nexport interface CancelParams {\n subscriptionId: string;\n reason?: string;\n immediate?: boolean;\n}\n\n/**\n * Subscription resource for managing subscriptions (plan-first model)\n *\n * Each customer can only have ONE active subscription at a time.\n */\nexport class SubscriptionsResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Create a subscription with a plan\n *\n * @example\n * ```typescript\n * await commet.subscriptions.create({\n * externalId: 'user_123',\n * planCode: 'pro', // autocomplete works after `commet pull`\n * billingInterval: 'yearly',\n * initialSeats: { editor: 5 }\n * });\n * ```\n */\n async create(\n params: CreateSubscriptionParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<CreatedSubscription>> {\n return this.httpClient.post(\"/subscriptions\", params, options);\n }\n\n /**\n * Get the active subscription for a customer\n *\n * @example\n * ```typescript\n * const sub = await commet.subscriptions.get('user_123');\n * ```\n */\n async get(\n externalId: string,\n ): Promise<ApiResponse<ActiveSubscription | null>> {\n return this.httpClient.get(\"/subscriptions/active\", { externalId });\n }\n\n /**\n * Cancel a subscription\n *\n * @example\n * ```typescript\n * await commet.subscriptions.cancel({\n * subscriptionId: 'sub_xxx',\n * reason: 'switched_to_competitor'\n * });\n * ```\n */\n async cancel(\n params: CancelParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Subscription>> {\n return this.httpClient.post(\n `/subscriptions/${params.subscriptionId}/cancel`,\n params || {},\n options,\n );\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n EventID,\n GeneratedFeatureCode,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface UsageEvent {\n id: EventID;\n organizationId: string;\n customerId: CustomerID;\n feature: string;\n idempotencyKey?: string;\n ts: string;\n properties?: UsageEventProperty[];\n createdAt: string;\n}\n\nexport interface UsageEventProperty {\n id: string;\n usageEventId: EventID;\n property: string;\n value: string;\n createdAt: string;\n}\n\nexport interface BatchResult<T> {\n successful: T[];\n failed: Array<{\n index: number;\n error: string;\n data: TrackParams;\n }>;\n}\n\nexport interface TrackParams {\n feature: GeneratedFeatureCode;\n customerId?: CustomerID;\n externalId?: string;\n idempotencyKey?: string;\n value?: number;\n timestamp?: string;\n properties?: Record<string, string>;\n}\n\n/**\n * Usage resource - Track consumption events for usage-based billing\n */\nexport class UsageResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Track a usage event\n *\n * @example\n * ```typescript\n * await commet.usage.track({\n * externalId: 'user_123',\n * feature: 'api_call',\n * value: 1,\n * idempotencyKey: `evt_${requestId}`,\n * properties: { endpoint: '/users', method: 'GET' }\n * });\n * ```\n */\n async track(\n params: TrackParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<UsageEvent>> {\n const eventData = {\n feature: params.feature,\n customerId: params.customerId,\n externalId: params.externalId,\n idempotencyKey: params.idempotencyKey,\n value: params.value,\n timestamp: params.timestamp || new Date().toISOString(),\n properties: params.properties\n ? Object.entries(params.properties).map(([property, value]) => ({\n property,\n value,\n }))\n : undefined,\n };\n\n return this.httpClient.post(\"/usage/events\", eventData, options);\n }\n\n /**\n * Track multiple usage events in a batch\n *\n * @example\n * ```typescript\n * await commet.usage.trackBatch({\n * events: [\n * { externalId: 'user_123', feature: 'api_call', value: 1, idempotencyKey: 'evt_1' },\n * { externalId: 'user_456', feature: 'api_call', value: 5, idempotencyKey: 'evt_2' }\n * ]\n * });\n * ```\n */\n async trackBatch(\n params: { events: TrackParams[] },\n options?: RequestOptions,\n ): Promise<ApiResponse<BatchResult<UsageEvent>>> {\n const events = params.events.map((event) => ({\n feature: event.feature,\n customerId: event.customerId,\n externalId: event.externalId,\n idempotencyKey: event.idempotencyKey,\n value: event.value,\n timestamp: event.timestamp || new Date().toISOString(),\n properties: event.properties\n ? Object.entries(event.properties).map(([property, value]) => ({\n property,\n value,\n }))\n : undefined,\n }));\n\n return this.httpClient.post(\"/usage/events/batch\", { events }, options);\n }\n}\n","import crypto from \"node:crypto\";\n\n/**\n * Webhook payload structure from Commet\n */\nexport interface WebhookPayload {\n event: WebhookEvent;\n timestamp: string;\n organizationId: string;\n data: WebhookData;\n}\n\n/**\n * Webhook data structure (subscription-related fields)\n */\nexport interface WebhookData {\n id?: string;\n publicId?: string;\n subscriptionId?: string;\n customerId?: string;\n externalId?: string;\n status?: string;\n name?: string;\n canceledAt?: string;\n [key: string]: unknown;\n}\n\n/**\n * Supported webhook events\n */\nexport type WebhookEvent =\n | \"subscription.created\"\n | \"subscription.activated\"\n | \"subscription.canceled\"\n | \"subscription.updated\";\n\nexport interface VerifyParams {\n payload: string;\n signature: string | null;\n secret: string;\n}\n\nexport interface GenerateSignatureParams {\n payload: string;\n secret: string;\n}\n\nexport interface VerifyAndParseParams {\n rawBody: string;\n signature: string | null;\n secret: string;\n}\n\n/**\n * Webhooks resource for signature verification\n */\nexport class Webhooks {\n /**\n * Verify HMAC-SHA256 webhook signature\n *\n * Use this method to verify that webhooks are authentically from Commet.\n * The signature is included in the `X-Commet-Signature` header.\n *\n * @param payload - Raw request body as string (IMPORTANT: Do not parse JSON first)\n * @param signature - Value from X-Commet-Signature header\n * @param secret - Your webhook secret from Commet dashboard\n * @returns true if signature is valid, false otherwise\n *\n * @example\n * ```typescript\n * // Next.js API route example\n * export async function POST(request: Request) {\n * const rawBody = await request.text();\n * const signature = request.headers.get('x-commet-signature');\n *\n * const isValid = commet.webhooks.verify(\n * rawBody,\n * signature,\n * process.env.COMMET_WEBHOOK_SECRET\n * );\n *\n * if (!isValid) {\n * return new Response('Invalid signature', { status: 401 });\n * }\n *\n * const payload = JSON.parse(rawBody);\n * // Handle webhook event...\n * }\n * ```\n */\n verify(params: VerifyParams): boolean {\n const { payload, signature, secret } = params;\n\n if (!signature || !secret || !payload) {\n return false;\n }\n\n try {\n const expectedSignature = this.generateSignature({ payload, secret });\n\n // Use timing-safe comparison to prevent timing attacks\n return crypto.timingSafeEqual(\n Buffer.from(signature, \"hex\"),\n Buffer.from(expectedSignature, \"hex\"),\n );\n } catch (error) {\n // timingSafeEqual throws if lengths don't match\n return false;\n }\n }\n\n /**\n * Generate HMAC-SHA256 signature (internal use)\n * @internal\n */\n private generateSignature(params: GenerateSignatureParams): string {\n const { payload, secret } = params;\n return crypto.createHmac(\"sha256\", secret).update(payload).digest(\"hex\");\n }\n\n /**\n * Parse and verify webhook payload in one step\n *\n * @example\n * ```typescript\n * const payload = commet.webhooks.verifyAndParse({\n * rawBody,\n * signature,\n * secret: process.env.COMMET_WEBHOOK_SECRET\n * });\n *\n * if (!payload) {\n * return new Response('Invalid signature', { status: 401 });\n * }\n *\n * // payload is typed and validated\n * if (payload.event === 'subscription.activated') {\n * // Handle activation...\n * }\n * ```\n */\n verifyAndParse(params: VerifyAndParseParams): WebhookPayload | null {\n const { rawBody, signature, secret } = params;\n\n if (!this.verify({ payload: rawBody, signature, secret })) {\n return null;\n }\n\n try {\n return JSON.parse(params.rawBody) as WebhookPayload;\n } catch {\n return null;\n }\n }\n}\n","export type Environment = \"sandbox\" | \"production\";\n\nexport type CommetConfig = {\n apiKey: string;\n environment?: Environment;\n debug?: boolean;\n timeout?: number;\n retries?: number;\n};\n\n// API Response types\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n code?: string;\n message?: string;\n details?: unknown;\n // Pagination fields (optional, included for list endpoints)\n hasMore?: boolean;\n nextCursor?: string;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n hasMore: boolean;\n nextCursor?: string;\n totalCount?: number;\n}\n\nexport interface PaginatedList<T> extends PaginatedResponse<T> {\n next(): Promise<PaginatedList<T>>;\n all(): Promise<T[]>;\n}\n\n// Error types\nexport class CommetError extends Error {\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommetError\";\n }\n}\n\nexport class CommetAPIError extends CommetError {\n constructor(\n message: string,\n public statusCode: number,\n public code?: string,\n public details?: unknown,\n ) {\n super(message, code, statusCode, details);\n this.name = \"CommetAPIError\";\n }\n}\n\nexport class CommetValidationError extends CommetError {\n constructor(\n message: string,\n public validationErrors: Record<string, string[]>,\n ) {\n super(message);\n this.name = \"CommetValidationError\";\n }\n}\n\nexport type CustomerID = `cus_${string}`;\nexport type AgreementID = `agr_${string}`;\nexport type InvoiceID = `inv_${string}`;\nexport type PhaseID = `phs_${string}`;\nexport type ItemID = `itm_${string}`;\nexport type ProductID = `prd_${string}`;\nexport type EventID = `evt_${string}`;\nexport type WebhookID = `wh_${string}`;\n\n// Currency enum\nexport type Currency =\n | \"USD\"\n | \"EUR\"\n | \"GBP\"\n | \"CAD\"\n | \"AUD\"\n | \"JPY\"\n | \"ARS\"\n | \"BRL\"\n | \"MXN\"\n | \"CLP\";\n\n// Common parameters\nexport interface ListParams extends Record<string, unknown> {\n limit?: number;\n cursor?: string;\n startDate?: string;\n endDate?: string;\n}\n\nexport interface RetrieveOptions {\n expand?: string[];\n}\n\n// Request options\nexport interface RequestOptions {\n idempotencyKey?: string;\n timeout?: number;\n}\n\n/**\n * Generated types interface - augmented by CLI after 'commet pull'\n *\n * This interface gets filled by module augmentation when you run `commet pull`.\n * The CLI generates a .commet/types.d.ts file that augments this interface with your\n * organization's specific feature codes, seat types, and plan codes.\n *\n * @example\n * // After running `commet pull`, TypeScript will automatically know your types:\n * await commet.usage.track({\n * feature: 'api_calls', // Autocomplete works!\n * externalId: 'user_123'\n * });\n */\n\n// biome-ignore lint/suspicious/noEmptyInterface: augmented by CLI-generated .commet/types.d.ts\nexport interface CommetGeneratedTypes {}\n\nexport type GeneratedSeatType = CommetGeneratedTypes extends {\n seatType: infer T;\n}\n ? T\n : string;\n\nexport type GeneratedPlanCode = CommetGeneratedTypes extends {\n planCode: infer T;\n}\n ? T\n : string;\n\nexport type GeneratedFeatureCode = CommetGeneratedTypes extends {\n featureCode: infer T;\n}\n ? T\n : string;\n","import type {\n ApiResponse,\n CommetConfig,\n Environment,\n RequestOptions,\n} from \"../types/common\";\nimport { CommetAPIError, CommetValidationError } from \"../types/common\";\n\nexport interface RetryConfig {\n maxRetries: number;\n baseDelay: number;\n maxDelay: number;\n retryableStatusCodes: number[];\n}\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 1000, // 1s\n maxDelay: 8000, // 8s\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\nexport class CommetHTTPClient {\n private config: CommetConfig;\n private environment: Environment;\n private retryConfig: RetryConfig;\n\n constructor(config: CommetConfig, environment: Environment) {\n this.config = config;\n this.environment = environment;\n this.retryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n maxRetries: config.retries ?? DEFAULT_RETRY_CONFIG.maxRetries,\n };\n }\n\n async get<T = unknown>(\n endpoint: string,\n params?: Record<string, unknown>,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"GET\", endpoint, undefined, options, params);\n }\n\n async post<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"POST\", endpoint, data, options);\n }\n\n async put<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"PUT\", endpoint, data, options);\n }\n\n async delete<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"DELETE\", endpoint, data, options);\n }\n\n /**\n * Core request method with retry logic\n */\n private async request<T = unknown>(\n method: string,\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n params?: Record<string, unknown>,\n ): Promise<ApiResponse<T>> {\n const url = this.buildURL(endpoint, params);\n return this.executeRequest(method, url, data, options);\n }\n\n /**\n * Execute real API request with retry logic\n */\n private async executeRequest<T = unknown>(\n method: string,\n url: string,\n data?: unknown,\n options?: RequestOptions,\n attempt = 1,\n ): Promise<ApiResponse<T>> {\n try {\n const headers: Record<string, string> = {\n \"x-api-key\": this.config.apiKey,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"commet/0.1.0\",\n };\n\n if (options?.idempotencyKey) {\n headers[\"Idempotency-Key\"] = options.idempotencyKey;\n } else if (method === \"POST\" && data) {\n headers[\"Idempotency-Key\"] = this.generateIdempotencyKey();\n }\n\n const requestConfig: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(\n options?.timeout ?? this.config.timeout ?? 30000,\n ),\n };\n\n if (data) {\n requestConfig.body = JSON.stringify(data);\n }\n\n if (this.config.debug) {\n console.log(`[Commet SDK] ${method} ${url}`);\n if (data) {\n console.log(\"Request data:\", JSON.stringify(data, null, 2));\n }\n }\n\n const response = await fetch(url, requestConfig);\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Response status: ${response.status} ${response.statusText}`,\n );\n }\n\n let responseData: unknown;\n let responseText: string;\n\n try {\n responseData = await response.json();\n responseText = \"\";\n } catch (jsonError) {\n try {\n responseText = await response.text();\n } catch (textError) {\n responseText = \"Failed to read response body\";\n }\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Failed to parse JSON response:\",\n responseText,\n );\n }\n\n // For 404 errors with invalid JSON, return a graceful response\n // This handles cases like HTML error pages or empty responses\n if (response.status === 404) {\n return {\n success: false,\n code: \"not_found\",\n message: \"Resource not found\",\n } as ApiResponse<T>;\n }\n\n throw new CommetAPIError(\n `Invalid JSON response: ${response.status} ${response.statusText}`,\n response.status,\n \"INVALID_JSON\",\n { responseText },\n );\n }\n\n if (!response.ok) {\n // Check if we should retry\n if (\n attempt <= this.retryConfig.maxRetries &&\n this.retryConfig.retryableStatusCodes.includes(response.status)\n ) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Retrying in ${delay}ms (attempt ${attempt}/${this.retryConfig.maxRetries})`,\n );\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n\n // Log error response for debugging\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Error response:\",\n JSON.stringify(responseData, null, 2),\n );\n }\n\n // Type guard for error response\n const isErrorResponse = (\n data: unknown,\n ): data is {\n message?: string;\n code?: string;\n details?: unknown;\n } => {\n return typeof data === \"object\" && data !== null;\n };\n\n const errorData = isErrorResponse(responseData) ? responseData : {};\n\n // Handle validation errors (new normalized shape)\n if (\n errorData.code === \"validation_error\" &&\n Array.isArray(errorData.details)\n ) {\n const errors: Record<string, string[]> = {};\n for (const detail of errorData.details as Array<{\n field: string;\n message: string;\n }>) {\n if (!errors[detail.field]) errors[detail.field] = [];\n errors[detail.field].push(detail.message);\n }\n throw new CommetValidationError(\n errorData.message || \"Validation failed\",\n errors,\n );\n }\n\n throw new CommetAPIError(\n errorData.message || `Request failed with status ${response.status}`,\n response.status,\n errorData.code,\n errorData.details,\n );\n }\n\n if (this.config.debug) {\n console.log(\"[Commet SDK] Response:\", responseData);\n }\n\n return responseData as ApiResponse<T>;\n } catch (error) {\n // Handle network errors and timeouts\n if (error instanceof TypeError && error.message.includes(\"fetch\")) {\n if (attempt <= this.retryConfig.maxRetries) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(`[Commet SDK] Network error, retrying in ${delay}ms`);\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Get base URL based on environment\n */\n private getBaseURL(): string {\n return this.environment === \"production\"\n ? \"https://commet.co\"\n : \"https://sandbox.commet.co\";\n }\n\n /**\n * Build full URL from endpoint and params\n */\n private buildURL(endpoint: string, params?: Record<string, unknown>): string {\n const baseURL = this.getBaseURL();\n\n // Construct full path with /api prefix\n const normalizedEndpoint = endpoint.startsWith(\"/\")\n ? endpoint\n : `/${endpoint}`;\n const fullPath = `/api${normalizedEndpoint}`;\n\n // Debug logging\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Building URL - baseURL: ${baseURL}, endpoint: ${endpoint}, fullPath: ${fullPath}`,\n );\n }\n\n const url = new URL(fullPath, baseURL);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n }\n }\n\n const finalUrl = url.toString();\n\n // Debug final URL\n if (this.config.debug) {\n console.log(`[Commet SDK] Final URL: ${finalUrl}`);\n }\n\n return finalUrl;\n }\n\n /**\n * Generate idempotency key\n */\n private generateIdempotencyKey(): string {\n // Generate UUID-like key for idempotency\n return `sdk_${Date.now()}_${Math.random().toString(36).substring(2)}`;\n }\n\n /**\n * Sleep for specified milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { CustomerContext } from \"./customer\";\nimport { CreditPacksResource } from \"./resources/credit-packs\";\nimport { CustomersResource } from \"./resources/customers\";\nimport { FeaturesResource } from \"./resources/features\";\nimport { PlansResource } from \"./resources/plans\";\nimport { PortalResource } from \"./resources/portal\";\nimport { SeatsResource } from \"./resources/seats\";\nimport { SubscriptionsResource } from \"./resources/subscriptions\";\nimport { UsageResource } from \"./resources/usage\";\nimport { Webhooks } from \"./resources/webhooks\";\nimport type { CommetConfig, Environment } from \"./types/common\";\nimport { CommetHTTPClient } from \"./utils/http\";\n\n/**\n * Main Commet SDK client\n */\nexport class Commet {\n private httpClient: CommetHTTPClient;\n private environment: Environment;\n\n public readonly customers: CustomersResource;\n public readonly creditPacks: CreditPacksResource;\n public readonly plans: PlansResource;\n public readonly usage: UsageResource;\n public readonly seats: SeatsResource;\n public readonly subscriptions: SubscriptionsResource;\n public readonly portal: PortalResource;\n public readonly features: FeaturesResource;\n public readonly webhooks: Webhooks;\n\n constructor(config: CommetConfig) {\n if (!config.apiKey) {\n throw new Error(\"Commet SDK: API key is required\");\n }\n\n if (!config.apiKey.startsWith(\"ck_\")) {\n throw new Error(\n \"Commet SDK: Invalid API key format. Expected format: ck_xxx...\",\n );\n }\n\n // Default to sandbox for safety\n this.environment = config.environment || \"sandbox\";\n\n this.httpClient = new CommetHTTPClient(config, this.environment);\n this.customers = new CustomersResource(this.httpClient);\n this.creditPacks = new CreditPacksResource(this.httpClient);\n this.plans = new PlansResource(this.httpClient);\n this.usage = new UsageResource(this.httpClient);\n this.seats = new SeatsResource(this.httpClient);\n this.subscriptions = new SubscriptionsResource(this.httpClient);\n this.portal = new PortalResource(this.httpClient);\n this.features = new FeaturesResource(this.httpClient);\n this.webhooks = new Webhooks();\n\n if (config.debug) {\n console.log(`[Commet SDK] Initialized in ${this.environment} mode`);\n console.log(\"API Key:\", `${config.apiKey.substring(0, 12)}...`);\n const baseURL =\n this.environment === \"production\"\n ? \"https://commet.co\"\n : \"https://sandbox.commet.co\";\n console.log(\"Base URL:\", baseURL);\n }\n }\n\n /**\n * Create a customer-scoped context for cleaner API usage\n *\n * @example\n * ```typescript\n * const customer = commet.customer(\"user_123\");\n *\n * // All operations are now scoped to this customer\n * const seats = await customer.features.get(\"team_members\");\n * await customer.seats.add(\"member\");\n * await customer.usage.track(\"api_call\");\n * ```\n */\n customer(externalId: string): CustomerContext {\n return new CustomerContext(externalId, {\n features: this.features,\n seats: this.seats,\n usage: this.usage,\n subscriptions: this.subscriptions,\n portal: this.portal,\n });\n }\n\n getEnvironment(): Environment {\n return this.environment;\n }\n\n isSandbox(): boolean {\n return this.environment === \"sandbox\";\n }\n\n isProduction(): boolean {\n return this.environment === \"production\";\n }\n}\n","import type { Environment } from \"../types/common\";\n\n/**\n * Check if environment is sandbox\n */\nexport function isSandbox(environment: Environment): boolean {\n return environment === \"sandbox\";\n}\n\n/**\n * Check if environment is production\n */\nexport function isProduction(environment: Environment): boolean {\n return environment === \"production\";\n}\n"],"mappings":"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","names":["crypto","data"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/customer.ts","../src/resources/credit-packs.ts","../src/resources/customers.ts","../src/resources/features.ts","../src/resources/plans.ts","../src/resources/portal.ts","../src/resources/seats.ts","../src/resources/subscriptions.ts","../src/resources/usage.ts","../src/resources/webhooks.ts","../src/types/common.ts","../src/utils/http.ts","../src/client.ts","../src/utils/environment.ts"],"sourcesContent":["/**\n * Commet SDK - Billing and usage tracking for SaaS\n */\nexport { Commet } from \"./client\";\nexport { CustomerContext } from \"./customer\";\n\n// Type exports\nexport type {\n CommetConfig,\n CommetGeneratedTypes,\n GeneratedSeatType,\n GeneratedPlanCode,\n GeneratedFeatureCode,\n Environment,\n ApiResponse,\n PaginatedResponse,\n PaginatedList,\n Currency,\n CustomerID,\n EventID,\n RequestOptions,\n} from \"./types/common\";\n\n// Error exports\nexport {\n CommetError,\n CommetAPIError,\n CommetValidationError,\n} from \"./types/common\";\n\n// Customers\nexport type {\n Customer,\n CustomerAddress,\n CreateParams as CreateCustomerParams,\n UpdateParams as UpdateCustomerParams,\n ListCustomersParams,\n BatchResult as CustomersBatchResult,\n} from \"./resources/customers\";\n\n// Usage\nexport type {\n UsageEvent,\n UsageEventProperty,\n TrackParams,\n TrackUsageParams,\n TrackModelTokensParams,\n BatchResult as UsageBatchResult,\n} from \"./resources/usage\";\n\n// Seats\nexport type {\n SeatEvent,\n SeatBalance,\n AddParams as AddSeatsParams,\n RemoveParams as RemoveSeatsParams,\n SetParams as SetSeatsParams,\n SetAllParams as SetAllSeatsParams,\n GetBalanceParams,\n GetAllBalancesParams,\n} from \"./resources/seats\";\n\n// Credit Packs\nexport type { CreditPack } from \"./resources/credit-packs\";\n\n// Plans\nexport type {\n Plan,\n PlanDetail,\n PlanPrice,\n PlanFeature,\n PlanID,\n BillingInterval,\n FeatureType,\n ListPlansParams,\n} from \"./resources/plans\";\n\n// Subscriptions\nexport type {\n CreatedSubscription,\n Subscription,\n ActiveSubscription,\n SubscriptionStatus,\n FeatureSummary,\n CreateSubscriptionParams,\n CancelParams,\n} from \"./resources/subscriptions\";\n\n// Portal\nexport type { PortalAccess, GetUrlParams } from \"./resources/portal\";\n\n// Features\nexport type {\n FeatureAccess,\n CanUseResult,\n CheckResult,\n GetFeatureParams,\n CheckFeatureParams,\n CanUseFeatureParams,\n} from \"./resources/features\";\n\n// Webhooks\nexport { Webhooks } from \"./resources/webhooks\";\nexport type {\n WebhookPayload,\n WebhookData,\n WebhookEvent,\n} from \"./resources/webhooks\";\n\n// Utility exports\nexport { isSandbox, isProduction } from \"./utils/environment\";\n\n// Default export\nimport { Commet } from \"./client\";\nexport default Commet;\n","import type { FeaturesResource } from \"./resources/features\";\nimport type { PortalResource } from \"./resources/portal\";\nimport type { SeatsResource } from \"./resources/seats\";\nimport type { SubscriptionsResource } from \"./resources/subscriptions\";\nimport type { UsageResource } from \"./resources/usage\";\nimport type { RequestOptions } from \"./types/common\";\n\n/**\n * Customer-scoped API context\n *\n * Provides a cleaner API where you don't have to pass externalId\n * on every call. All operations are scoped to a specific customer.\n *\n * @example\n * ```typescript\n * const customer = commet.customer(\"user_123\");\n *\n * // All operations are now scoped to this customer\n * const seats = await customer.features.get(\"team_members\");\n * await customer.seats.add(\"member\");\n * await customer.usage.track(\"api_call\");\n * ```\n */\nexport class CustomerContext {\n private readonly externalId: string;\n private readonly featuresResource: FeaturesResource;\n private readonly seatsResource: SeatsResource;\n private readonly usageResource: UsageResource;\n private readonly subscriptionsResource: SubscriptionsResource;\n private readonly portalResource: PortalResource;\n\n constructor(\n externalId: string,\n resources: {\n features: FeaturesResource;\n seats: SeatsResource;\n usage: UsageResource;\n subscriptions: SubscriptionsResource;\n portal: PortalResource;\n },\n ) {\n this.externalId = externalId;\n this.featuresResource = resources.features;\n this.seatsResource = resources.seats;\n this.usageResource = resources.usage;\n this.subscriptionsResource = resources.subscriptions;\n this.portalResource = resources.portal;\n }\n\n /**\n * Feature access methods - delegates to FeaturesResource\n */\n features = {\n get: (code: string, options?: RequestOptions) =>\n this.featuresResource.get({ code, externalId: this.externalId }, options),\n\n check: (code: string, options?: RequestOptions) =>\n this.featuresResource.check(\n { code, externalId: this.externalId },\n options,\n ),\n\n canUse: (code: string, options?: RequestOptions) =>\n this.featuresResource.canUse(\n { code, externalId: this.externalId },\n options,\n ),\n\n list: (options?: RequestOptions) =>\n this.featuresResource.list(this.externalId, options),\n };\n\n /**\n * Seat management methods - delegates to SeatsResource\n */\n seats = {\n add: (seatType: string, count = 1, options?: RequestOptions) =>\n this.seatsResource.add(\n { externalId: this.externalId, seatType, count },\n options,\n ),\n\n remove: (seatType: string, count = 1, options?: RequestOptions) =>\n this.seatsResource.remove(\n { externalId: this.externalId, seatType, count },\n options,\n ),\n\n set: (seatType: string, count: number, options?: RequestOptions) =>\n this.seatsResource.set(\n { externalId: this.externalId, seatType, count },\n options,\n ),\n\n getBalance: (seatType: string) =>\n this.seatsResource.getBalance({ externalId: this.externalId, seatType }),\n };\n\n /**\n * Usage tracking methods - delegates to UsageResource\n */\n usage = {\n track: (\n feature: string,\n value?: number,\n properties?: Record<string, string>,\n options?: RequestOptions,\n ) =>\n this.usageResource.track(\n { externalId: this.externalId, feature, value, properties },\n options,\n ),\n };\n\n /**\n * Subscription methods - delegates to SubscriptionsResource\n */\n subscription = {\n get: () => this.subscriptionsResource.get(this.externalId),\n };\n\n /**\n * Portal methods - delegates to PortalResource\n */\n portal = {\n getUrl: (options?: RequestOptions) =>\n this.portalResource.getUrl({ externalId: this.externalId }, options),\n };\n}\n","import type { ApiResponse } from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface CreditPack {\n id: string;\n name: string;\n description: string | null;\n credits: number;\n price: number;\n currency: string;\n}\n\n/**\n * Credit Packs resource for listing available credit packs\n */\nexport class CreditPacksResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * List all active credit packs\n *\n * @example\n * ```typescript\n * const packs = await commet.creditPacks.list();\n * console.log(packs.data); // [{ id: \"cp_xxx\", name: \"100 Credits\", ... }]\n * ```\n */\n async list(): Promise<ApiResponse<CreditPack[]>> {\n return this.httpClient.get(\"/credit-packs\");\n }\n}\n","import type {\n ApiResponse,\n ListParams as BaseListParams,\n CustomerID,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface Customer {\n id: CustomerID;\n organizationId: string;\n externalId?: string;\n fullName?: string;\n domain?: string;\n website?: string;\n billingEmail: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CustomerAddress {\n line1: string;\n line2?: string;\n city: string;\n state?: string;\n postalCode: string;\n country: string; // ISO-2\n}\n\nexport interface CreateParams {\n email: string; // billingEmail - the only required field\n externalId?: string;\n fullName?: string;\n domain?: string;\n website?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n metadata?: Record<string, unknown>;\n address?: CustomerAddress;\n}\n\nexport interface UpdateParams {\n customerId: CustomerID;\n externalId?: string;\n email?: string;\n fullName?: string;\n domain?: string;\n website?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ListCustomersParams extends BaseListParams {\n externalId?: string;\n isActive?: boolean;\n search?: string;\n}\n\nexport interface BatchResult {\n successful: Customer[];\n failed: Array<{\n index: number;\n error: string;\n data: CreateParams;\n }>;\n}\n\n/**\n * Customers resource - Manage your customers\n */\nexport class CustomersResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Create a customer (idempotent with externalId)\n */\n async create(\n params: CreateParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.post(\n \"/customers\",\n {\n billingEmail: params.email,\n externalId: params.externalId,\n fullName: params.fullName,\n domain: params.domain,\n website: params.website,\n timezone: params.timezone,\n language: params.language,\n industry: params.industry,\n metadata: params.metadata,\n address: params.address,\n },\n options,\n );\n }\n\n /**\n * Create multiple customers in batch\n */\n async createBatch(\n params: { customers: CreateParams[] },\n options?: RequestOptions,\n ): Promise<ApiResponse<BatchResult>> {\n const customers = params.customers.map((c) => ({\n billingEmail: c.email,\n externalId: c.externalId,\n fullName: c.fullName,\n domain: c.domain,\n website: c.website,\n timezone: c.timezone,\n language: c.language,\n industry: c.industry,\n metadata: c.metadata,\n address: c.address,\n }));\n return this.httpClient.post(\"/customers/batch\", { customers }, options);\n }\n\n /**\n * Get a customer by ID\n */\n async get(customerId: CustomerID): Promise<ApiResponse<Customer>> {\n return this.httpClient.get(`/customers/${customerId}`);\n }\n\n /**\n * Update a customer\n */\n async update(\n params: UpdateParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(\n `/customers/${params.customerId}`,\n {\n billingEmail: params.email,\n externalId: params.externalId,\n fullName: params.fullName,\n domain: params.domain,\n website: params.website,\n timezone: params.timezone,\n language: params.language,\n industry: params.industry,\n metadata: params.metadata,\n },\n options,\n );\n }\n\n /**\n * List customers with optional filters\n */\n async list(params?: ListCustomersParams): Promise<ApiResponse<Customer[]>> {\n return this.httpClient.get(\"/customers\", params as Record<string, unknown>);\n }\n\n /**\n * Archive a customer\n */\n async archive(\n customerId: CustomerID,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(\n `/customers/${customerId}`,\n { isActive: false },\n options,\n );\n }\n}\n","import type {\n ApiResponse,\n GeneratedFeatureCode,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface FeatureParams {\n externalId: string;\n code: GeneratedFeatureCode;\n}\n\nexport type GetFeatureParams = FeatureParams;\nexport type CheckFeatureParams = FeatureParams;\nexport type CanUseFeatureParams = FeatureParams;\n\nexport interface FeatureAccess {\n code: string;\n name: string;\n type: \"boolean\" | \"metered\" | \"seats\";\n allowed: boolean;\n // For boolean features\n enabled?: boolean;\n // For metered/seats features\n current?: number;\n included?: number;\n remaining?: number;\n overage?: number;\n overageUnitPrice?: number;\n unlimited?: boolean;\n overageEnabled?: boolean;\n}\n\nexport interface CanUseResult {\n allowed: boolean;\n willBeCharged: boolean;\n reason?: string;\n}\n\nexport interface CheckResult {\n allowed: boolean;\n}\n\n/**\n * Features resource for checking feature access and usage\n *\n * Provides a clean API to check if a customer can use a feature\n * without having to manually parse subscription data.\n */\nexport class FeaturesResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Get detailed feature access/usage for a customer\n *\n * @example\n * ```typescript\n * const seats = await commet.features.get({ code: \"team_members\", externalId: \"user_123\" });\n * console.log(seats.current, seats.included, seats.remaining);\n * ```\n */\n async get(\n params: GetFeatureParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<FeatureAccess>> {\n const { code, externalId } = params;\n\n return this.httpClient.get(\n `/features/${code}`,\n { externalId: externalId },\n options,\n );\n }\n\n /**\n * Check if a boolean feature is enabled for a customer\n *\n * @example\n * ```typescript\n * const { allowed } = await commet.features.check({\n * code: \"custom_branding\",\n * externalId: \"user_123\"\n * });\n * if (!allowed) redirect(\"/upgrade\");\n * ```\n */\n async check(\n params: CheckFeatureParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<CheckResult>> {\n const { code, externalId } = params;\n\n const result = await this.httpClient.get<FeatureAccess>(\n `/features/${code}`,\n { externalId: externalId },\n options,\n );\n\n if (!result.success || !result.data) {\n return {\n success: false,\n data: { allowed: false },\n message: result.message,\n };\n }\n\n return {\n success: true,\n data: { allowed: result.data.allowed },\n message: result.message,\n };\n }\n\n /**\n * Check if customer can use one more unit of a feature\n *\n * Returns whether the customer can add one more (allowed)\n * and whether they'll be charged extra (willBeCharged).\n *\n * @example\n * ```typescript\n * const { allowed, willBeCharged } = await commet.features.canUse({\n * code: \"team_members\",\n * externalId: \"user_123\"\n * });\n *\n * if (!allowed) {\n * return { error: \"Upgrade to add more members\" };\n * }\n *\n * if (willBeCharged) {\n * // Show confirmation: \"This will cost $10/month extra\"\n * }\n * ```\n */\n async canUse(\n params: CanUseFeatureParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<CanUseResult>> {\n const { code, externalId } = params;\n\n return this.httpClient.get(\n `/features/${code}`,\n { externalId: externalId, action: \"canUse\" },\n options,\n );\n }\n\n /**\n * List all features for a customer's active subscription\n *\n * @example\n * ```typescript\n * const features = await commet.features.list({ externalId: \"user_123\" });\n * for (const feature of features) {\n * console.log(feature.code, feature.allowed);\n * }\n * ```\n */\n async list(\n externalId: string,\n options?: RequestOptions,\n ): Promise<ApiResponse<FeatureAccess[]>> {\n return this.httpClient.get(\"/features\", { externalId }, options);\n }\n}\n","import type {\n ApiResponse,\n GeneratedPlanCode,\n ListParams,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport type PlanID = `plan_${string}`;\nexport type BillingInterval = \"monthly\" | \"quarterly\" | \"yearly\";\nexport type FeatureType = \"boolean\" | \"metered\" | \"seats\";\n\nexport interface PlanPrice {\n billingInterval: BillingInterval;\n price: number; // in cents\n isDefault: boolean;\n trialDays: number;\n}\n\nexport interface PlanFeature {\n code: string;\n name: string;\n type: FeatureType;\n unitName: string | null;\n enabled?: boolean;\n includedAmount?: number;\n unlimited?: boolean;\n overageEnabled?: boolean;\n overageUnitPrice?: number;\n}\n\nexport interface Plan {\n id: PlanID;\n code: string;\n name: string;\n description: string | null;\n isPublic: boolean;\n isFree: boolean;\n isDefault: boolean;\n sortOrder: number;\n prices: PlanPrice[];\n features: PlanFeature[];\n createdAt: string;\n}\n\nexport interface PlanDetailPrice {\n billingInterval: BillingInterval;\n price: number;\n isDefault: boolean;\n trialDays: number;\n introOffer: {\n enabled: boolean;\n discountType: \"percentage\" | \"amount\" | null;\n discountValue: number | null;\n durationCycles: number | null;\n } | null;\n}\n\nexport interface PlanDetailFeature extends PlanFeature {\n overage: {\n enabled: boolean;\n model: \"per_unit\" | \"tiered\" | null;\n unitPrice: number | null;\n } | null;\n}\n\nexport interface PlanDetail {\n id: PlanID;\n code: string;\n name: string;\n description: string | null;\n isPublic: boolean;\n isDefault: boolean;\n sortOrder: number;\n prices: PlanDetailPrice[];\n features: PlanDetailFeature[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ListPlansParams extends ListParams {\n includePrivate?: boolean;\n}\n\n/**\n * Plans resource for listing available plans\n */\nexport class PlansResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * List all available plans\n *\n * @example\n * ```typescript\n * // List public plans\n * const plans = await commet.plans.list();\n *\n * // Include private plans\n * const allPlans = await commet.plans.list({ includePrivate: true });\n * ```\n */\n async list(params?: ListPlansParams): Promise<ApiResponse<Plan[]>> {\n return this.httpClient.get(\"/plans\", params);\n }\n\n /**\n * Get a specific plan by code\n *\n * @example\n * ```typescript\n * const plan = await commet.plans.get('pro');\n * console.log(plan.data.name); // \"Pro\"\n * console.log(plan.data.prices); // [{ billingInterval: 'monthly', price: 9900 }]\n * ```\n */\n async get(planCode: GeneratedPlanCode): Promise<ApiResponse<PlanDetail>> {\n return this.httpClient.get(`/plans/${planCode}`);\n }\n}\n","import type { ApiResponse, CustomerID, RequestOptions } from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface PortalAccess {\n success: boolean;\n message: string;\n portalUrl: string;\n}\n\ninterface GetUrlByCustomerId {\n customerId: CustomerID;\n email?: never;\n externalId?: never;\n}\n\ninterface GetUrlByExternalId {\n externalId: string;\n email?: never;\n customerId?: never;\n}\n\ninterface GetUrlByEmail {\n email: string;\n customerId?: never;\n externalId?: never;\n}\n\nexport type GetUrlParams =\n | GetUrlByCustomerId\n | GetUrlByExternalId\n | GetUrlByEmail;\n\n/**\n * Portal resource - Generate customer portal access\n */\nexport class PortalResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Get a portal URL\n *\n * @example\n * ```typescript\n * const portal = await commet.portal.getUrl({ externalId: 'user_123' });\n * ```\n */\n async getUrl(\n params: GetUrlParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<PortalAccess>> {\n return this.httpClient.post(\"/portal/request-access\", params, options);\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n GeneratedSeatType,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface SeatEvent {\n id: string;\n organizationId: string;\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n eventType: \"add\" | \"remove\" | \"set\";\n quantity: number;\n previousBalance?: number;\n newBalance: number;\n ts: string;\n createdAt: string;\n}\n\nexport interface SeatBalance {\n current: number;\n asOf: string;\n}\n\nexport interface AddParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface RemoveParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface SetParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface SetAllParams {\n customerId?: CustomerID;\n externalId?: string;\n seats: Record<string, number>;\n}\n\nexport interface GetBalanceParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n}\n\nexport interface GetAllBalancesParams {\n customerId?: CustomerID;\n externalId?: string;\n}\n\n/**\n * Seats resource - Manage seat-based licenses\n */\nexport class SeatsResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Add seats\n *\n * @example\n * ```typescript\n * await commet.seats.add({\n * externalId: 'user_123',\n * seatType: 'editor',\n * count: 5\n * });\n * ```\n */\n async add(\n params: AddParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.post(\"/seats\", params, options);\n }\n\n /**\n * Remove seats\n *\n * @example\n * ```typescript\n * await commet.seats.remove({\n * externalId: 'user_123',\n * seatType: 'editor',\n * count: 2\n * });\n * ```\n */\n async remove(\n params: RemoveParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.delete(\"/seats\", params, options);\n }\n\n /**\n * Set seats to a specific count\n *\n * @example\n * ```typescript\n * await commet.seats.set({\n * externalId: 'user_123',\n * seatType: 'editor',\n * count: 10\n * });\n * ```\n */\n async set(\n params: SetParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.put(\"/seats\", params, options);\n }\n\n /**\n * Set all seat types\n *\n * @example\n * ```typescript\n * await commet.seats.setAll({\n * externalId: 'user_123',\n * seats: { editor: 10, viewer: 50 }\n * });\n * ```\n */\n async setAll(\n params: SetAllParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent[]>> {\n return this.httpClient.put(\"/seats/bulk\", params, options);\n }\n\n /**\n * Get balance for a seat type\n *\n * @example\n * ```typescript\n * const balance = await commet.seats.getBalance({\n * externalId: 'user_123',\n * seatType: 'editor'\n * });\n * ```\n */\n async getBalance(\n params: GetBalanceParams,\n ): Promise<ApiResponse<SeatBalance>> {\n const { customerId, externalId, seatType } = params;\n\n return this.httpClient.get(\"/seats/balance\", {\n customerId: customerId,\n externalId: externalId,\n seatType: seatType,\n });\n }\n\n /**\n * Get all seat balances\n *\n * @example\n * ```typescript\n * const balances = await commet.seats.getAllBalances({\n * externalId: 'user_123'\n * });\n * ```\n */\n async getAllBalances(\n params: GetAllBalancesParams,\n ): Promise<ApiResponse<Record<string, SeatBalance>>> {\n const { customerId, externalId } = params;\n\n return this.httpClient.get(\"/seats/balances\", {\n customerId: customerId,\n externalId: externalId,\n });\n }\n}\n","import type {\n ApiResponse,\n GeneratedPlanCode,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\nimport type { BillingInterval } from \"./plans\";\n\nexport type SubscriptionStatus =\n | \"draft\"\n | \"pending_payment\"\n | \"trialing\"\n | \"active\"\n | \"paused\"\n | \"past_due\"\n | \"canceled\"\n | \"expired\";\n\nexport interface FeatureSummary {\n code: string;\n name: string;\n type: \"boolean\" | \"metered\" | \"seats\";\n enabled?: boolean;\n usage?: {\n current: number;\n included: number;\n overage: number;\n overageUnitPrice?: number;\n };\n}\n\nexport interface ActiveSubscription {\n id: string;\n customerId: string;\n plan: {\n id: string;\n name: string;\n basePrice: number;\n billingInterval: BillingInterval | null;\n };\n name: string;\n description: string | null;\n status: SubscriptionStatus;\n trialEndsAt: string | null;\n currentPeriod: {\n start: string;\n end: string;\n daysRemaining: number;\n };\n features: FeatureSummary[];\n startDate: string;\n endDate: string | null;\n billingDayOfMonth: number;\n nextBillingDate: string;\n checkoutUrl: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreatedSubscription {\n id: string;\n customerId: string;\n externalId: string;\n planId: string;\n planName: string;\n name: string;\n status: SubscriptionStatus;\n billingInterval: BillingInterval | null;\n trialEndsAt: string | null;\n startDate: string;\n endDate: string | null;\n currentPeriodStart: string | null;\n currentPeriodEnd: string | null;\n billingDayOfMonth: number;\n checkoutUrl: string | null;\n createdAt: string;\n updatedAt: string;\n introOfferEndsAt: string | null;\n introOfferDiscountType: \"percentage\" | \"amount\" | null;\n introOfferDiscountValue: number | null;\n}\n\nexport interface Subscription {\n id: string;\n customerId: string;\n planId: string;\n planName: string;\n name: string;\n description?: string;\n status: SubscriptionStatus;\n billingInterval: BillingInterval;\n trialEndsAt?: string;\n startDate: string;\n endDate?: string;\n currentPeriodStart?: string;\n currentPeriodEnd?: string;\n billingDayOfMonth: number;\n checkoutUrl?: string;\n createdAt: string;\n updatedAt: string;\n}\n\n// Customer identifier: mutually exclusive customerId or externalId\ntype CustomerIdentifier =\n | { customerId: string; externalId?: never }\n | { customerId?: never; externalId: string };\n\n// Plan identifier: use planCode (with autocomplete) or planId (legacy)\ntype PlanIdentifier =\n | { planCode: GeneratedPlanCode; planId?: never }\n | { planCode?: never; planId: string };\n\nexport type CreateSubscriptionParams = CustomerIdentifier &\n PlanIdentifier & {\n billingInterval?: BillingInterval;\n initialSeats?: Record<string, number>;\n skipTrial?: boolean;\n name?: string;\n startDate?: string;\n successUrl?: string;\n };\n\nexport interface CancelParams {\n subscriptionId: string;\n reason?: string;\n immediate?: boolean;\n}\n\n/**\n * Subscription resource for managing subscriptions (plan-first model)\n *\n * Each customer can only have ONE active subscription at a time.\n */\nexport class SubscriptionsResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Create a subscription with a plan\n *\n * @example\n * ```typescript\n * await commet.subscriptions.create({\n * externalId: 'user_123',\n * planCode: 'pro', // autocomplete works after `commet pull`\n * billingInterval: 'yearly',\n * initialSeats: { editor: 5 }\n * });\n * ```\n */\n async create(\n params: CreateSubscriptionParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<CreatedSubscription>> {\n return this.httpClient.post(\"/subscriptions\", params, options);\n }\n\n /**\n * Get the active subscription for a customer\n *\n * @example\n * ```typescript\n * const sub = await commet.subscriptions.get('user_123');\n * ```\n */\n async get(\n externalId: string,\n ): Promise<ApiResponse<ActiveSubscription | null>> {\n return this.httpClient.get(\"/subscriptions/active\", { externalId });\n }\n\n /**\n * Cancel a subscription\n *\n * @example\n * ```typescript\n * await commet.subscriptions.cancel({\n * subscriptionId: 'sub_xxx',\n * reason: 'switched_to_competitor'\n * });\n * ```\n */\n async cancel(\n params: CancelParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Subscription>> {\n return this.httpClient.post(\n `/subscriptions/${params.subscriptionId}/cancel`,\n params || {},\n options,\n );\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n EventID,\n GeneratedFeatureCode,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface UsageEvent {\n id: EventID;\n organizationId: string;\n customerId: CustomerID;\n feature: string;\n idempotencyKey?: string;\n ts: string;\n properties?: UsageEventProperty[];\n createdAt: string;\n}\n\nexport interface UsageEventProperty {\n id: string;\n usageEventId: EventID;\n property: string;\n value: string;\n createdAt: string;\n}\n\nexport interface BatchResult<T> {\n successful: T[];\n failed: Array<{\n index: number;\n error: string;\n data: TrackParams;\n }>;\n}\n\ninterface TrackBaseParams {\n feature: GeneratedFeatureCode;\n customerId?: CustomerID;\n externalId?: string;\n idempotencyKey?: string;\n timestamp?: string;\n properties?: Record<string, string>;\n}\n\nexport interface TrackUsageParams extends TrackBaseParams {\n value?: number;\n model?: never;\n}\n\nexport interface TrackModelTokensParams extends TrackBaseParams {\n model: string;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n value?: never;\n}\n\nexport type TrackParams = TrackUsageParams | TrackModelTokensParams;\n\nexport class UsageResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async track(\n params: TrackParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<UsageEvent>> {\n const eventData: Record<string, unknown> = {\n feature: params.feature,\n customerId: params.customerId,\n externalId: params.externalId,\n idempotencyKey: params.idempotencyKey,\n timestamp: params.timestamp || new Date().toISOString(),\n properties: params.properties\n ? Object.entries(params.properties).map(([property, value]) => ({\n property,\n value,\n }))\n : undefined,\n };\n\n if (\"model\" in params && params.model) {\n eventData.model = params.model;\n eventData.inputTokens = params.inputTokens;\n eventData.outputTokens = params.outputTokens;\n if (params.cacheReadTokens) {\n eventData.cacheReadTokens = params.cacheReadTokens;\n }\n if (params.cacheWriteTokens) {\n eventData.cacheWriteTokens = params.cacheWriteTokens;\n }\n } else {\n eventData.value = (params as TrackUsageParams).value;\n }\n\n return this.httpClient.post(\"/usage/events\", eventData, options);\n }\n\n async trackBatch(\n params: { events: TrackParams[] },\n options?: RequestOptions,\n ): Promise<ApiResponse<BatchResult<UsageEvent>>> {\n const events = params.events.map((event) => {\n const eventData: Record<string, unknown> = {\n feature: event.feature,\n customerId: event.customerId,\n externalId: event.externalId,\n idempotencyKey: event.idempotencyKey,\n timestamp: event.timestamp || new Date().toISOString(),\n properties: event.properties\n ? Object.entries(event.properties).map(([property, value]) => ({\n property,\n value,\n }))\n : undefined,\n };\n\n if (\"model\" in event && event.model) {\n eventData.model = event.model;\n eventData.inputTokens = event.inputTokens;\n eventData.outputTokens = event.outputTokens;\n if (event.cacheReadTokens) {\n eventData.cacheReadTokens = event.cacheReadTokens;\n }\n if (event.cacheWriteTokens) {\n eventData.cacheWriteTokens = event.cacheWriteTokens;\n }\n } else {\n eventData.value = (event as TrackUsageParams).value;\n }\n\n return eventData;\n });\n\n return this.httpClient.post(\"/usage/events/batch\", { events }, options);\n }\n}\n","import crypto from \"node:crypto\";\n\n/**\n * Webhook payload structure from Commet\n */\nexport interface WebhookPayload {\n event: WebhookEvent;\n timestamp: string;\n organizationId: string;\n data: WebhookData;\n}\n\n/**\n * Webhook data structure (subscription-related fields)\n */\nexport interface WebhookData {\n id?: string;\n publicId?: string;\n subscriptionId?: string;\n customerId?: string;\n externalId?: string;\n status?: string;\n name?: string;\n canceledAt?: string;\n [key: string]: unknown;\n}\n\n/**\n * Supported webhook events\n */\nexport type WebhookEvent =\n | \"subscription.created\"\n | \"subscription.activated\"\n | \"subscription.canceled\"\n | \"subscription.updated\";\n\nexport interface VerifyParams {\n payload: string;\n signature: string | null;\n secret: string;\n}\n\nexport interface GenerateSignatureParams {\n payload: string;\n secret: string;\n}\n\nexport interface VerifyAndParseParams {\n rawBody: string;\n signature: string | null;\n secret: string;\n}\n\n/**\n * Webhooks resource for signature verification\n */\nexport class Webhooks {\n /**\n * Verify HMAC-SHA256 webhook signature\n *\n * Use this method to verify that webhooks are authentically from Commet.\n * The signature is included in the `X-Commet-Signature` header.\n *\n * @param payload - Raw request body as string (IMPORTANT: Do not parse JSON first)\n * @param signature - Value from X-Commet-Signature header\n * @param secret - Your webhook secret from Commet dashboard\n * @returns true if signature is valid, false otherwise\n *\n * @example\n * ```typescript\n * // Next.js API route example\n * export async function POST(request: Request) {\n * const rawBody = await request.text();\n * const signature = request.headers.get('x-commet-signature');\n *\n * const isValid = commet.webhooks.verify(\n * rawBody,\n * signature,\n * process.env.COMMET_WEBHOOK_SECRET\n * );\n *\n * if (!isValid) {\n * return new Response('Invalid signature', { status: 401 });\n * }\n *\n * const payload = JSON.parse(rawBody);\n * // Handle webhook event...\n * }\n * ```\n */\n verify(params: VerifyParams): boolean {\n const { payload, signature, secret } = params;\n\n if (!signature || !secret || !payload) {\n return false;\n }\n\n try {\n const expectedSignature = this.generateSignature({ payload, secret });\n\n // Use timing-safe comparison to prevent timing attacks\n return crypto.timingSafeEqual(\n Buffer.from(signature, \"hex\"),\n Buffer.from(expectedSignature, \"hex\"),\n );\n } catch (error) {\n // timingSafeEqual throws if lengths don't match\n return false;\n }\n }\n\n /**\n * Generate HMAC-SHA256 signature (internal use)\n * @internal\n */\n private generateSignature(params: GenerateSignatureParams): string {\n const { payload, secret } = params;\n return crypto.createHmac(\"sha256\", secret).update(payload).digest(\"hex\");\n }\n\n /**\n * Parse and verify webhook payload in one step\n *\n * @example\n * ```typescript\n * const payload = commet.webhooks.verifyAndParse({\n * rawBody,\n * signature,\n * secret: process.env.COMMET_WEBHOOK_SECRET\n * });\n *\n * if (!payload) {\n * return new Response('Invalid signature', { status: 401 });\n * }\n *\n * // payload is typed and validated\n * if (payload.event === 'subscription.activated') {\n * // Handle activation...\n * }\n * ```\n */\n verifyAndParse(params: VerifyAndParseParams): WebhookPayload | null {\n const { rawBody, signature, secret } = params;\n\n if (!this.verify({ payload: rawBody, signature, secret })) {\n return null;\n }\n\n try {\n return JSON.parse(params.rawBody) as WebhookPayload;\n } catch {\n return null;\n }\n }\n}\n","export type Environment = \"sandbox\" | \"production\";\n\nexport type CommetConfig = {\n apiKey: string;\n environment?: Environment;\n debug?: boolean;\n timeout?: number;\n retries?: number;\n};\n\n// API Response types\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n code?: string;\n message?: string;\n details?: unknown;\n // Pagination fields (optional, included for list endpoints)\n hasMore?: boolean;\n nextCursor?: string;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n hasMore: boolean;\n nextCursor?: string;\n totalCount?: number;\n}\n\nexport interface PaginatedList<T> extends PaginatedResponse<T> {\n next(): Promise<PaginatedList<T>>;\n all(): Promise<T[]>;\n}\n\n// Error types\nexport class CommetError extends Error {\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommetError\";\n }\n}\n\nexport class CommetAPIError extends CommetError {\n constructor(\n message: string,\n public statusCode: number,\n public code?: string,\n public details?: unknown,\n ) {\n super(message, code, statusCode, details);\n this.name = \"CommetAPIError\";\n }\n}\n\nexport class CommetValidationError extends CommetError {\n constructor(\n message: string,\n public validationErrors: Record<string, string[]>,\n ) {\n super(message);\n this.name = \"CommetValidationError\";\n }\n}\n\nexport type CustomerID = `cus_${string}`;\nexport type AgreementID = `agr_${string}`;\nexport type InvoiceID = `inv_${string}`;\nexport type PhaseID = `phs_${string}`;\nexport type ItemID = `itm_${string}`;\nexport type ProductID = `prd_${string}`;\nexport type EventID = `evt_${string}`;\nexport type WebhookID = `wh_${string}`;\n\n// Currency enum\nexport type Currency =\n | \"USD\"\n | \"EUR\"\n | \"GBP\"\n | \"CAD\"\n | \"AUD\"\n | \"JPY\"\n | \"ARS\"\n | \"BRL\"\n | \"MXN\"\n | \"CLP\";\n\n// Common parameters\nexport interface ListParams extends Record<string, unknown> {\n limit?: number;\n cursor?: string;\n startDate?: string;\n endDate?: string;\n}\n\nexport interface RetrieveOptions {\n expand?: string[];\n}\n\n// Request options\nexport interface RequestOptions {\n idempotencyKey?: string;\n timeout?: number;\n}\n\n/**\n * Generated types interface - augmented by CLI after 'commet pull'\n *\n * This interface gets filled by module augmentation when you run `commet pull`.\n * The CLI generates a .commet/types.d.ts file that augments this interface with your\n * organization's specific feature codes, seat types, and plan codes.\n *\n * @example\n * // After running `commet pull`, TypeScript will automatically know your types:\n * await commet.usage.track({\n * feature: 'api_calls', // Autocomplete works!\n * externalId: 'user_123'\n * });\n */\n\n// biome-ignore lint/suspicious/noEmptyInterface: augmented by CLI-generated .commet/types.d.ts\nexport interface CommetGeneratedTypes {}\n\nexport type GeneratedSeatType = CommetGeneratedTypes extends {\n seatType: infer T;\n}\n ? T\n : string;\n\nexport type GeneratedPlanCode = CommetGeneratedTypes extends {\n planCode: infer T;\n}\n ? T\n : string;\n\nexport type GeneratedFeatureCode = CommetGeneratedTypes extends {\n featureCode: infer T;\n}\n ? T\n : string;\n","import type {\n ApiResponse,\n CommetConfig,\n Environment,\n RequestOptions,\n} from \"../types/common\";\nimport { CommetAPIError, CommetValidationError } from \"../types/common\";\n\nexport interface RetryConfig {\n maxRetries: number;\n baseDelay: number;\n maxDelay: number;\n retryableStatusCodes: number[];\n}\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 1000, // 1s\n maxDelay: 8000, // 8s\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\nexport class CommetHTTPClient {\n private config: CommetConfig;\n private environment: Environment;\n private retryConfig: RetryConfig;\n\n constructor(config: CommetConfig, environment: Environment) {\n this.config = config;\n this.environment = environment;\n this.retryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n maxRetries: config.retries ?? DEFAULT_RETRY_CONFIG.maxRetries,\n };\n }\n\n async get<T = unknown>(\n endpoint: string,\n params?: Record<string, unknown>,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"GET\", endpoint, undefined, options, params);\n }\n\n async post<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"POST\", endpoint, data, options);\n }\n\n async put<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"PUT\", endpoint, data, options);\n }\n\n async delete<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"DELETE\", endpoint, data, options);\n }\n\n /**\n * Core request method with retry logic\n */\n private async request<T = unknown>(\n method: string,\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n params?: Record<string, unknown>,\n ): Promise<ApiResponse<T>> {\n const url = this.buildURL(endpoint, params);\n return this.executeRequest(method, url, data, options);\n }\n\n /**\n * Execute real API request with retry logic\n */\n private async executeRequest<T = unknown>(\n method: string,\n url: string,\n data?: unknown,\n options?: RequestOptions,\n attempt = 1,\n ): Promise<ApiResponse<T>> {\n try {\n const headers: Record<string, string> = {\n \"x-api-key\": this.config.apiKey,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"commet/0.1.0\",\n };\n\n if (options?.idempotencyKey) {\n headers[\"Idempotency-Key\"] = options.idempotencyKey;\n } else if (method === \"POST\" && data) {\n headers[\"Idempotency-Key\"] = this.generateIdempotencyKey();\n }\n\n const requestConfig: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(\n options?.timeout ?? this.config.timeout ?? 30000,\n ),\n };\n\n if (data) {\n requestConfig.body = JSON.stringify(data);\n }\n\n if (this.config.debug) {\n console.log(`[Commet SDK] ${method} ${url}`);\n if (data) {\n console.log(\"Request data:\", JSON.stringify(data, null, 2));\n }\n }\n\n const response = await fetch(url, requestConfig);\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Response status: ${response.status} ${response.statusText}`,\n );\n }\n\n let responseData: unknown;\n let responseText: string;\n\n try {\n responseData = await response.json();\n responseText = \"\";\n } catch (jsonError) {\n try {\n responseText = await response.text();\n } catch (textError) {\n responseText = \"Failed to read response body\";\n }\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Failed to parse JSON response:\",\n responseText,\n );\n }\n\n // For 404 errors with invalid JSON, return a graceful response\n // This handles cases like HTML error pages or empty responses\n if (response.status === 404) {\n return {\n success: false,\n code: \"not_found\",\n message: \"Resource not found\",\n } as ApiResponse<T>;\n }\n\n throw new CommetAPIError(\n `Invalid JSON response: ${response.status} ${response.statusText}`,\n response.status,\n \"INVALID_JSON\",\n { responseText },\n );\n }\n\n if (!response.ok) {\n // Check if we should retry\n if (\n attempt <= this.retryConfig.maxRetries &&\n this.retryConfig.retryableStatusCodes.includes(response.status)\n ) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Retrying in ${delay}ms (attempt ${attempt}/${this.retryConfig.maxRetries})`,\n );\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n\n // Log error response for debugging\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Error response:\",\n JSON.stringify(responseData, null, 2),\n );\n }\n\n // Type guard for error response\n const isErrorResponse = (\n data: unknown,\n ): data is {\n message?: string;\n code?: string;\n details?: unknown;\n } => {\n return typeof data === \"object\" && data !== null;\n };\n\n const errorData = isErrorResponse(responseData) ? responseData : {};\n\n // Handle validation errors (new normalized shape)\n if (\n errorData.code === \"validation_error\" &&\n Array.isArray(errorData.details)\n ) {\n const errors: Record<string, string[]> = {};\n for (const detail of errorData.details as Array<{\n field: string;\n message: string;\n }>) {\n if (!errors[detail.field]) errors[detail.field] = [];\n errors[detail.field].push(detail.message);\n }\n throw new CommetValidationError(\n errorData.message || \"Validation failed\",\n errors,\n );\n }\n\n throw new CommetAPIError(\n errorData.message || `Request failed with status ${response.status}`,\n response.status,\n errorData.code,\n errorData.details,\n );\n }\n\n if (this.config.debug) {\n console.log(\"[Commet SDK] Response:\", responseData);\n }\n\n return responseData as ApiResponse<T>;\n } catch (error) {\n // Handle network errors and timeouts\n if (error instanceof TypeError && error.message.includes(\"fetch\")) {\n if (attempt <= this.retryConfig.maxRetries) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(`[Commet SDK] Network error, retrying in ${delay}ms`);\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Get base URL based on environment\n */\n private getBaseURL(): string {\n return this.environment === \"production\"\n ? \"https://commet.co\"\n : \"https://sandbox.commet.co\";\n }\n\n /**\n * Build full URL from endpoint and params\n */\n private buildURL(endpoint: string, params?: Record<string, unknown>): string {\n const baseURL = this.getBaseURL();\n\n // Construct full path with /api prefix\n const normalizedEndpoint = endpoint.startsWith(\"/\")\n ? endpoint\n : `/${endpoint}`;\n const fullPath = `/api${normalizedEndpoint}`;\n\n // Debug logging\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Building URL - baseURL: ${baseURL}, endpoint: ${endpoint}, fullPath: ${fullPath}`,\n );\n }\n\n const url = new URL(fullPath, baseURL);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n }\n }\n\n const finalUrl = url.toString();\n\n // Debug final URL\n if (this.config.debug) {\n console.log(`[Commet SDK] Final URL: ${finalUrl}`);\n }\n\n return finalUrl;\n }\n\n /**\n * Generate idempotency key\n */\n private generateIdempotencyKey(): string {\n // Generate UUID-like key for idempotency\n return `sdk_${Date.now()}_${Math.random().toString(36).substring(2)}`;\n }\n\n /**\n * Sleep for specified milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { CustomerContext } from \"./customer\";\nimport { CreditPacksResource } from \"./resources/credit-packs\";\nimport { CustomersResource } from \"./resources/customers\";\nimport { FeaturesResource } from \"./resources/features\";\nimport { PlansResource } from \"./resources/plans\";\nimport { PortalResource } from \"./resources/portal\";\nimport { SeatsResource } from \"./resources/seats\";\nimport { SubscriptionsResource } from \"./resources/subscriptions\";\nimport { UsageResource } from \"./resources/usage\";\nimport { Webhooks } from \"./resources/webhooks\";\nimport type { CommetConfig, Environment } from \"./types/common\";\nimport { CommetHTTPClient } from \"./utils/http\";\n\n/**\n * Main Commet SDK client\n */\nexport class Commet {\n private httpClient: CommetHTTPClient;\n private environment: Environment;\n\n public readonly customers: CustomersResource;\n public readonly creditPacks: CreditPacksResource;\n public readonly plans: PlansResource;\n public readonly usage: UsageResource;\n public readonly seats: SeatsResource;\n public readonly subscriptions: SubscriptionsResource;\n public readonly portal: PortalResource;\n public readonly features: FeaturesResource;\n public readonly webhooks: Webhooks;\n\n constructor(config: CommetConfig) {\n if (!config.apiKey) {\n throw new Error(\"Commet SDK: API key is required\");\n }\n\n if (!config.apiKey.startsWith(\"ck_\")) {\n throw new Error(\n \"Commet SDK: Invalid API key format. Expected format: ck_xxx...\",\n );\n }\n\n // Default to sandbox for safety\n this.environment = config.environment || \"sandbox\";\n\n this.httpClient = new CommetHTTPClient(config, this.environment);\n this.customers = new CustomersResource(this.httpClient);\n this.creditPacks = new CreditPacksResource(this.httpClient);\n this.plans = new PlansResource(this.httpClient);\n this.usage = new UsageResource(this.httpClient);\n this.seats = new SeatsResource(this.httpClient);\n this.subscriptions = new SubscriptionsResource(this.httpClient);\n this.portal = new PortalResource(this.httpClient);\n this.features = new FeaturesResource(this.httpClient);\n this.webhooks = new Webhooks();\n\n if (config.debug) {\n console.log(`[Commet SDK] Initialized in ${this.environment} mode`);\n console.log(\"API Key:\", `${config.apiKey.substring(0, 12)}...`);\n const baseURL =\n this.environment === \"production\"\n ? \"https://commet.co\"\n : \"https://sandbox.commet.co\";\n console.log(\"Base URL:\", baseURL);\n }\n }\n\n /**\n * Create a customer-scoped context for cleaner API usage\n *\n * @example\n * ```typescript\n * const customer = commet.customer(\"user_123\");\n *\n * // All operations are now scoped to this customer\n * const seats = await customer.features.get(\"team_members\");\n * await customer.seats.add(\"member\");\n * await customer.usage.track(\"api_call\");\n * ```\n */\n customer(externalId: string): CustomerContext {\n return new CustomerContext(externalId, {\n features: this.features,\n seats: this.seats,\n usage: this.usage,\n subscriptions: this.subscriptions,\n portal: this.portal,\n });\n }\n\n getEnvironment(): Environment {\n return this.environment;\n }\n\n isSandbox(): boolean {\n return this.environment === \"sandbox\";\n }\n\n isProduction(): boolean {\n return this.environment === \"production\";\n }\n}\n","import type { Environment } from \"../types/common\";\n\n/**\n * Check if environment is sandbox\n */\nexport function isSandbox(environment: Environment): boolean {\n return environment === \"sandbox\";\n}\n\n/**\n * Check if environment is production\n */\nexport function isProduction(environment: Environment): boolean {\n return environment === \"production\";\n}\n"],"mappings":"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","names":["crypto","data"]}
package/dist/index.mjs CHANGED
@@ -483,61 +483,61 @@ var UsageResource = class {
483
483
  constructor(httpClient) {
484
484
  this.httpClient = httpClient;
485
485
  }
486
- /**
487
- * Track a usage event
488
- *
489
- * @example
490
- * ```typescript
491
- * await commet.usage.track({
492
- * externalId: 'user_123',
493
- * feature: 'api_call',
494
- * value: 1,
495
- * idempotencyKey: `evt_${requestId}`,
496
- * properties: { endpoint: '/users', method: 'GET' }
497
- * });
498
- * ```
499
- */
500
486
  async track(params, options) {
501
487
  const eventData = {
502
488
  feature: params.feature,
503
489
  customerId: params.customerId,
504
490
  externalId: params.externalId,
505
491
  idempotencyKey: params.idempotencyKey,
506
- value: params.value,
507
492
  timestamp: params.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
508
493
  properties: params.properties ? Object.entries(params.properties).map(([property, value]) => ({
509
494
  property,
510
495
  value
511
496
  })) : void 0
512
497
  };
498
+ if ("model" in params && params.model) {
499
+ eventData.model = params.model;
500
+ eventData.inputTokens = params.inputTokens;
501
+ eventData.outputTokens = params.outputTokens;
502
+ if (params.cacheReadTokens) {
503
+ eventData.cacheReadTokens = params.cacheReadTokens;
504
+ }
505
+ if (params.cacheWriteTokens) {
506
+ eventData.cacheWriteTokens = params.cacheWriteTokens;
507
+ }
508
+ } else {
509
+ eventData.value = params.value;
510
+ }
513
511
  return this.httpClient.post("/usage/events", eventData, options);
514
512
  }
515
- /**
516
- * Track multiple usage events in a batch
517
- *
518
- * @example
519
- * ```typescript
520
- * await commet.usage.trackBatch({
521
- * events: [
522
- * { externalId: 'user_123', feature: 'api_call', value: 1, idempotencyKey: 'evt_1' },
523
- * { externalId: 'user_456', feature: 'api_call', value: 5, idempotencyKey: 'evt_2' }
524
- * ]
525
- * });
526
- * ```
527
- */
528
513
  async trackBatch(params, options) {
529
- const events = params.events.map((event) => ({
530
- feature: event.feature,
531
- customerId: event.customerId,
532
- externalId: event.externalId,
533
- idempotencyKey: event.idempotencyKey,
534
- value: event.value,
535
- timestamp: event.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
536
- properties: event.properties ? Object.entries(event.properties).map(([property, value]) => ({
537
- property,
538
- value
539
- })) : void 0
540
- }));
514
+ const events = params.events.map((event) => {
515
+ const eventData = {
516
+ feature: event.feature,
517
+ customerId: event.customerId,
518
+ externalId: event.externalId,
519
+ idempotencyKey: event.idempotencyKey,
520
+ timestamp: event.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
521
+ properties: event.properties ? Object.entries(event.properties).map(([property, value]) => ({
522
+ property,
523
+ value
524
+ })) : void 0
525
+ };
526
+ if ("model" in event && event.model) {
527
+ eventData.model = event.model;
528
+ eventData.inputTokens = event.inputTokens;
529
+ eventData.outputTokens = event.outputTokens;
530
+ if (event.cacheReadTokens) {
531
+ eventData.cacheReadTokens = event.cacheReadTokens;
532
+ }
533
+ if (event.cacheWriteTokens) {
534
+ eventData.cacheWriteTokens = event.cacheWriteTokens;
535
+ }
536
+ } else {
537
+ eventData.value = event.value;
538
+ }
539
+ return eventData;
540
+ });
541
541
  return this.httpClient.post("/usage/events/batch", { events }, options);
542
542
  }
543
543
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/customer.ts","../src/resources/credit-packs.ts","../src/resources/customers.ts","../src/resources/features.ts","../src/resources/plans.ts","../src/resources/portal.ts","../src/resources/seats.ts","../src/resources/subscriptions.ts","../src/resources/usage.ts","../src/resources/webhooks.ts","../src/types/common.ts","../src/utils/http.ts","../src/client.ts","../src/utils/environment.ts","../src/index.ts"],"sourcesContent":["import type { FeaturesResource } from \"./resources/features\";\nimport type { PortalResource } from \"./resources/portal\";\nimport type { SeatsResource } from \"./resources/seats\";\nimport type { SubscriptionsResource } from \"./resources/subscriptions\";\nimport type { UsageResource } from \"./resources/usage\";\nimport type { RequestOptions } from \"./types/common\";\n\n/**\n * Customer-scoped API context\n *\n * Provides a cleaner API where you don't have to pass externalId\n * on every call. All operations are scoped to a specific customer.\n *\n * @example\n * ```typescript\n * const customer = commet.customer(\"user_123\");\n *\n * // All operations are now scoped to this customer\n * const seats = await customer.features.get(\"team_members\");\n * await customer.seats.add(\"member\");\n * await customer.usage.track(\"api_call\");\n * ```\n */\nexport class CustomerContext {\n private readonly externalId: string;\n private readonly featuresResource: FeaturesResource;\n private readonly seatsResource: SeatsResource;\n private readonly usageResource: UsageResource;\n private readonly subscriptionsResource: SubscriptionsResource;\n private readonly portalResource: PortalResource;\n\n constructor(\n externalId: string,\n resources: {\n features: FeaturesResource;\n seats: SeatsResource;\n usage: UsageResource;\n subscriptions: SubscriptionsResource;\n portal: PortalResource;\n },\n ) {\n this.externalId = externalId;\n this.featuresResource = resources.features;\n this.seatsResource = resources.seats;\n this.usageResource = resources.usage;\n this.subscriptionsResource = resources.subscriptions;\n this.portalResource = resources.portal;\n }\n\n /**\n * Feature access methods - delegates to FeaturesResource\n */\n features = {\n get: (code: string, options?: RequestOptions) =>\n this.featuresResource.get({ code, externalId: this.externalId }, options),\n\n check: (code: string, options?: RequestOptions) =>\n this.featuresResource.check(\n { code, externalId: this.externalId },\n options,\n ),\n\n canUse: (code: string, options?: RequestOptions) =>\n this.featuresResource.canUse(\n { code, externalId: this.externalId },\n options,\n ),\n\n list: (options?: RequestOptions) =>\n this.featuresResource.list(this.externalId, options),\n };\n\n /**\n * Seat management methods - delegates to SeatsResource\n */\n seats = {\n add: (seatType: string, count = 1, options?: RequestOptions) =>\n this.seatsResource.add(\n { externalId: this.externalId, seatType, count },\n options,\n ),\n\n remove: (seatType: string, count = 1, options?: RequestOptions) =>\n this.seatsResource.remove(\n { externalId: this.externalId, seatType, count },\n options,\n ),\n\n set: (seatType: string, count: number, options?: RequestOptions) =>\n this.seatsResource.set(\n { externalId: this.externalId, seatType, count },\n options,\n ),\n\n getBalance: (seatType: string) =>\n this.seatsResource.getBalance({ externalId: this.externalId, seatType }),\n };\n\n /**\n * Usage tracking methods - delegates to UsageResource\n */\n usage = {\n track: (\n feature: string,\n value?: number,\n properties?: Record<string, string>,\n options?: RequestOptions,\n ) =>\n this.usageResource.track(\n { externalId: this.externalId, feature, value, properties },\n options,\n ),\n };\n\n /**\n * Subscription methods - delegates to SubscriptionsResource\n */\n subscription = {\n get: () => this.subscriptionsResource.get(this.externalId),\n };\n\n /**\n * Portal methods - delegates to PortalResource\n */\n portal = {\n getUrl: (options?: RequestOptions) =>\n this.portalResource.getUrl({ externalId: this.externalId }, options),\n };\n}\n","import type { ApiResponse } from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface CreditPack {\n id: string;\n name: string;\n description: string | null;\n credits: number;\n price: number;\n currency: string;\n}\n\n/**\n * Credit Packs resource for listing available credit packs\n */\nexport class CreditPacksResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * List all active credit packs\n *\n * @example\n * ```typescript\n * const packs = await commet.creditPacks.list();\n * console.log(packs.data); // [{ id: \"cp_xxx\", name: \"100 Credits\", ... }]\n * ```\n */\n async list(): Promise<ApiResponse<CreditPack[]>> {\n return this.httpClient.get(\"/credit-packs\");\n }\n}\n","import type {\n ApiResponse,\n ListParams as BaseListParams,\n CustomerID,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface Customer {\n id: CustomerID;\n organizationId: string;\n externalId?: string;\n fullName?: string;\n domain?: string;\n website?: string;\n billingEmail: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CustomerAddress {\n line1: string;\n line2?: string;\n city: string;\n state?: string;\n postalCode: string;\n country: string; // ISO-2\n}\n\nexport interface CreateParams {\n email: string; // billingEmail - the only required field\n externalId?: string;\n fullName?: string;\n domain?: string;\n website?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n metadata?: Record<string, unknown>;\n address?: CustomerAddress;\n}\n\nexport interface UpdateParams {\n customerId: CustomerID;\n externalId?: string;\n email?: string;\n fullName?: string;\n domain?: string;\n website?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ListCustomersParams extends BaseListParams {\n externalId?: string;\n isActive?: boolean;\n search?: string;\n}\n\nexport interface BatchResult {\n successful: Customer[];\n failed: Array<{\n index: number;\n error: string;\n data: CreateParams;\n }>;\n}\n\n/**\n * Customers resource - Manage your customers\n */\nexport class CustomersResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Create a customer (idempotent with externalId)\n */\n async create(\n params: CreateParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.post(\n \"/customers\",\n {\n billingEmail: params.email,\n externalId: params.externalId,\n fullName: params.fullName,\n domain: params.domain,\n website: params.website,\n timezone: params.timezone,\n language: params.language,\n industry: params.industry,\n metadata: params.metadata,\n address: params.address,\n },\n options,\n );\n }\n\n /**\n * Create multiple customers in batch\n */\n async createBatch(\n params: { customers: CreateParams[] },\n options?: RequestOptions,\n ): Promise<ApiResponse<BatchResult>> {\n const customers = params.customers.map((c) => ({\n billingEmail: c.email,\n externalId: c.externalId,\n fullName: c.fullName,\n domain: c.domain,\n website: c.website,\n timezone: c.timezone,\n language: c.language,\n industry: c.industry,\n metadata: c.metadata,\n address: c.address,\n }));\n return this.httpClient.post(\"/customers/batch\", { customers }, options);\n }\n\n /**\n * Get a customer by ID\n */\n async get(customerId: CustomerID): Promise<ApiResponse<Customer>> {\n return this.httpClient.get(`/customers/${customerId}`);\n }\n\n /**\n * Update a customer\n */\n async update(\n params: UpdateParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(\n `/customers/${params.customerId}`,\n {\n billingEmail: params.email,\n externalId: params.externalId,\n fullName: params.fullName,\n domain: params.domain,\n website: params.website,\n timezone: params.timezone,\n language: params.language,\n industry: params.industry,\n metadata: params.metadata,\n },\n options,\n );\n }\n\n /**\n * List customers with optional filters\n */\n async list(params?: ListCustomersParams): Promise<ApiResponse<Customer[]>> {\n return this.httpClient.get(\"/customers\", params as Record<string, unknown>);\n }\n\n /**\n * Archive a customer\n */\n async archive(\n customerId: CustomerID,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(\n `/customers/${customerId}`,\n { isActive: false },\n options,\n );\n }\n}\n","import type {\n ApiResponse,\n GeneratedFeatureCode,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface FeatureParams {\n externalId: string;\n code: GeneratedFeatureCode;\n}\n\nexport type GetFeatureParams = FeatureParams;\nexport type CheckFeatureParams = FeatureParams;\nexport type CanUseFeatureParams = FeatureParams;\n\nexport interface FeatureAccess {\n code: string;\n name: string;\n type: \"boolean\" | \"metered\" | \"seats\";\n allowed: boolean;\n // For boolean features\n enabled?: boolean;\n // For metered/seats features\n current?: number;\n included?: number;\n remaining?: number;\n overage?: number;\n overageUnitPrice?: number;\n unlimited?: boolean;\n overageEnabled?: boolean;\n}\n\nexport interface CanUseResult {\n allowed: boolean;\n willBeCharged: boolean;\n reason?: string;\n}\n\nexport interface CheckResult {\n allowed: boolean;\n}\n\n/**\n * Features resource for checking feature access and usage\n *\n * Provides a clean API to check if a customer can use a feature\n * without having to manually parse subscription data.\n */\nexport class FeaturesResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Get detailed feature access/usage for a customer\n *\n * @example\n * ```typescript\n * const seats = await commet.features.get({ code: \"team_members\", externalId: \"user_123\" });\n * console.log(seats.current, seats.included, seats.remaining);\n * ```\n */\n async get(\n params: GetFeatureParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<FeatureAccess>> {\n const { code, externalId } = params;\n\n return this.httpClient.get(\n `/features/${code}`,\n { externalId: externalId },\n options,\n );\n }\n\n /**\n * Check if a boolean feature is enabled for a customer\n *\n * @example\n * ```typescript\n * const { allowed } = await commet.features.check({\n * code: \"custom_branding\",\n * externalId: \"user_123\"\n * });\n * if (!allowed) redirect(\"/upgrade\");\n * ```\n */\n async check(\n params: CheckFeatureParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<CheckResult>> {\n const { code, externalId } = params;\n\n const result = await this.httpClient.get<FeatureAccess>(\n `/features/${code}`,\n { externalId: externalId },\n options,\n );\n\n if (!result.success || !result.data) {\n return {\n success: false,\n data: { allowed: false },\n message: result.message,\n };\n }\n\n return {\n success: true,\n data: { allowed: result.data.allowed },\n message: result.message,\n };\n }\n\n /**\n * Check if customer can use one more unit of a feature\n *\n * Returns whether the customer can add one more (allowed)\n * and whether they'll be charged extra (willBeCharged).\n *\n * @example\n * ```typescript\n * const { allowed, willBeCharged } = await commet.features.canUse({\n * code: \"team_members\",\n * externalId: \"user_123\"\n * });\n *\n * if (!allowed) {\n * return { error: \"Upgrade to add more members\" };\n * }\n *\n * if (willBeCharged) {\n * // Show confirmation: \"This will cost $10/month extra\"\n * }\n * ```\n */\n async canUse(\n params: CanUseFeatureParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<CanUseResult>> {\n const { code, externalId } = params;\n\n return this.httpClient.get(\n `/features/${code}`,\n { externalId: externalId, action: \"canUse\" },\n options,\n );\n }\n\n /**\n * List all features for a customer's active subscription\n *\n * @example\n * ```typescript\n * const features = await commet.features.list({ externalId: \"user_123\" });\n * for (const feature of features) {\n * console.log(feature.code, feature.allowed);\n * }\n * ```\n */\n async list(\n externalId: string,\n options?: RequestOptions,\n ): Promise<ApiResponse<FeatureAccess[]>> {\n return this.httpClient.get(\"/features\", { externalId }, options);\n }\n}\n","import type {\n ApiResponse,\n GeneratedPlanCode,\n ListParams,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport type PlanID = `plan_${string}`;\nexport type BillingInterval = \"monthly\" | \"quarterly\" | \"yearly\";\nexport type FeatureType = \"boolean\" | \"metered\" | \"seats\";\n\nexport interface PlanPrice {\n billingInterval: BillingInterval;\n price: number; // in cents\n isDefault: boolean;\n trialDays: number;\n}\n\nexport interface PlanFeature {\n code: string;\n name: string;\n type: FeatureType;\n unitName: string | null;\n enabled?: boolean;\n includedAmount?: number;\n unlimited?: boolean;\n overageEnabled?: boolean;\n overageUnitPrice?: number;\n}\n\nexport interface Plan {\n id: PlanID;\n code: string;\n name: string;\n description: string | null;\n isPublic: boolean;\n isFree: boolean;\n isDefault: boolean;\n sortOrder: number;\n prices: PlanPrice[];\n features: PlanFeature[];\n createdAt: string;\n}\n\nexport interface PlanDetailPrice {\n billingInterval: BillingInterval;\n price: number;\n isDefault: boolean;\n trialDays: number;\n introOffer: {\n enabled: boolean;\n discountType: \"percentage\" | \"amount\" | null;\n discountValue: number | null;\n durationCycles: number | null;\n } | null;\n}\n\nexport interface PlanDetailFeature extends PlanFeature {\n overage: {\n enabled: boolean;\n model: \"per_unit\" | \"tiered\" | null;\n unitPrice: number | null;\n } | null;\n}\n\nexport interface PlanDetail {\n id: PlanID;\n code: string;\n name: string;\n description: string | null;\n isPublic: boolean;\n isDefault: boolean;\n sortOrder: number;\n prices: PlanDetailPrice[];\n features: PlanDetailFeature[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ListPlansParams extends ListParams {\n includePrivate?: boolean;\n}\n\n/**\n * Plans resource for listing available plans\n */\nexport class PlansResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * List all available plans\n *\n * @example\n * ```typescript\n * // List public plans\n * const plans = await commet.plans.list();\n *\n * // Include private plans\n * const allPlans = await commet.plans.list({ includePrivate: true });\n * ```\n */\n async list(params?: ListPlansParams): Promise<ApiResponse<Plan[]>> {\n return this.httpClient.get(\"/plans\", params);\n }\n\n /**\n * Get a specific plan by code\n *\n * @example\n * ```typescript\n * const plan = await commet.plans.get('pro');\n * console.log(plan.data.name); // \"Pro\"\n * console.log(plan.data.prices); // [{ billingInterval: 'monthly', price: 9900 }]\n * ```\n */\n async get(planCode: GeneratedPlanCode): Promise<ApiResponse<PlanDetail>> {\n return this.httpClient.get(`/plans/${planCode}`);\n }\n}\n","import type { ApiResponse, CustomerID, RequestOptions } from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface PortalAccess {\n success: boolean;\n message: string;\n portalUrl: string;\n}\n\ninterface GetUrlByCustomerId {\n customerId: CustomerID;\n email?: never;\n externalId?: never;\n}\n\ninterface GetUrlByExternalId {\n externalId: string;\n email?: never;\n customerId?: never;\n}\n\ninterface GetUrlByEmail {\n email: string;\n customerId?: never;\n externalId?: never;\n}\n\nexport type GetUrlParams =\n | GetUrlByCustomerId\n | GetUrlByExternalId\n | GetUrlByEmail;\n\n/**\n * Portal resource - Generate customer portal access\n */\nexport class PortalResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Get a portal URL\n *\n * @example\n * ```typescript\n * const portal = await commet.portal.getUrl({ externalId: 'user_123' });\n * ```\n */\n async getUrl(\n params: GetUrlParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<PortalAccess>> {\n return this.httpClient.post(\"/portal/request-access\", params, options);\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n GeneratedSeatType,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface SeatEvent {\n id: string;\n organizationId: string;\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n eventType: \"add\" | \"remove\" | \"set\";\n quantity: number;\n previousBalance?: number;\n newBalance: number;\n ts: string;\n createdAt: string;\n}\n\nexport interface SeatBalance {\n current: number;\n asOf: string;\n}\n\nexport interface AddParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface RemoveParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface SetParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface SetAllParams {\n customerId?: CustomerID;\n externalId?: string;\n seats: Record<string, number>;\n}\n\nexport interface GetBalanceParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n}\n\nexport interface GetAllBalancesParams {\n customerId?: CustomerID;\n externalId?: string;\n}\n\n/**\n * Seats resource - Manage seat-based licenses\n */\nexport class SeatsResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Add seats\n *\n * @example\n * ```typescript\n * await commet.seats.add({\n * externalId: 'user_123',\n * seatType: 'editor',\n * count: 5\n * });\n * ```\n */\n async add(\n params: AddParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.post(\"/seats\", params, options);\n }\n\n /**\n * Remove seats\n *\n * @example\n * ```typescript\n * await commet.seats.remove({\n * externalId: 'user_123',\n * seatType: 'editor',\n * count: 2\n * });\n * ```\n */\n async remove(\n params: RemoveParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.delete(\"/seats\", params, options);\n }\n\n /**\n * Set seats to a specific count\n *\n * @example\n * ```typescript\n * await commet.seats.set({\n * externalId: 'user_123',\n * seatType: 'editor',\n * count: 10\n * });\n * ```\n */\n async set(\n params: SetParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.put(\"/seats\", params, options);\n }\n\n /**\n * Set all seat types\n *\n * @example\n * ```typescript\n * await commet.seats.setAll({\n * externalId: 'user_123',\n * seats: { editor: 10, viewer: 50 }\n * });\n * ```\n */\n async setAll(\n params: SetAllParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent[]>> {\n return this.httpClient.put(\"/seats/bulk\", params, options);\n }\n\n /**\n * Get balance for a seat type\n *\n * @example\n * ```typescript\n * const balance = await commet.seats.getBalance({\n * externalId: 'user_123',\n * seatType: 'editor'\n * });\n * ```\n */\n async getBalance(\n params: GetBalanceParams,\n ): Promise<ApiResponse<SeatBalance>> {\n const { customerId, externalId, seatType } = params;\n\n return this.httpClient.get(\"/seats/balance\", {\n customerId: customerId,\n externalId: externalId,\n seatType: seatType,\n });\n }\n\n /**\n * Get all seat balances\n *\n * @example\n * ```typescript\n * const balances = await commet.seats.getAllBalances({\n * externalId: 'user_123'\n * });\n * ```\n */\n async getAllBalances(\n params: GetAllBalancesParams,\n ): Promise<ApiResponse<Record<string, SeatBalance>>> {\n const { customerId, externalId } = params;\n\n return this.httpClient.get(\"/seats/balances\", {\n customerId: customerId,\n externalId: externalId,\n });\n }\n}\n","import type {\n ApiResponse,\n GeneratedPlanCode,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\nimport type { BillingInterval } from \"./plans\";\n\nexport type SubscriptionStatus =\n | \"draft\"\n | \"pending_payment\"\n | \"trialing\"\n | \"active\"\n | \"paused\"\n | \"past_due\"\n | \"canceled\"\n | \"expired\";\n\nexport interface FeatureSummary {\n code: string;\n name: string;\n type: \"boolean\" | \"metered\" | \"seats\";\n enabled?: boolean;\n usage?: {\n current: number;\n included: number;\n overage: number;\n overageUnitPrice?: number;\n };\n}\n\nexport interface ActiveSubscription {\n id: string;\n customerId: string;\n plan: {\n id: string;\n name: string;\n basePrice: number;\n billingInterval: BillingInterval | null;\n };\n name: string;\n description: string | null;\n status: SubscriptionStatus;\n trialEndsAt: string | null;\n currentPeriod: {\n start: string;\n end: string;\n daysRemaining: number;\n };\n features: FeatureSummary[];\n startDate: string;\n endDate: string | null;\n billingDayOfMonth: number;\n nextBillingDate: string;\n checkoutUrl: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreatedSubscription {\n id: string;\n customerId: string;\n externalId: string;\n planId: string;\n planName: string;\n name: string;\n status: SubscriptionStatus;\n billingInterval: BillingInterval | null;\n trialEndsAt: string | null;\n startDate: string;\n endDate: string | null;\n currentPeriodStart: string | null;\n currentPeriodEnd: string | null;\n billingDayOfMonth: number;\n checkoutUrl: string | null;\n createdAt: string;\n updatedAt: string;\n introOfferEndsAt: string | null;\n introOfferDiscountType: \"percentage\" | \"amount\" | null;\n introOfferDiscountValue: number | null;\n}\n\nexport interface Subscription {\n id: string;\n customerId: string;\n planId: string;\n planName: string;\n name: string;\n description?: string;\n status: SubscriptionStatus;\n billingInterval: BillingInterval;\n trialEndsAt?: string;\n startDate: string;\n endDate?: string;\n currentPeriodStart?: string;\n currentPeriodEnd?: string;\n billingDayOfMonth: number;\n checkoutUrl?: string;\n createdAt: string;\n updatedAt: string;\n}\n\n// Customer identifier: mutually exclusive customerId or externalId\ntype CustomerIdentifier =\n | { customerId: string; externalId?: never }\n | { customerId?: never; externalId: string };\n\n// Plan identifier: use planCode (with autocomplete) or planId (legacy)\ntype PlanIdentifier =\n | { planCode: GeneratedPlanCode; planId?: never }\n | { planCode?: never; planId: string };\n\nexport type CreateSubscriptionParams = CustomerIdentifier &\n PlanIdentifier & {\n billingInterval?: BillingInterval;\n initialSeats?: Record<string, number>;\n skipTrial?: boolean;\n name?: string;\n startDate?: string;\n successUrl?: string;\n };\n\nexport interface CancelParams {\n subscriptionId: string;\n reason?: string;\n immediate?: boolean;\n}\n\n/**\n * Subscription resource for managing subscriptions (plan-first model)\n *\n * Each customer can only have ONE active subscription at a time.\n */\nexport class SubscriptionsResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Create a subscription with a plan\n *\n * @example\n * ```typescript\n * await commet.subscriptions.create({\n * externalId: 'user_123',\n * planCode: 'pro', // autocomplete works after `commet pull`\n * billingInterval: 'yearly',\n * initialSeats: { editor: 5 }\n * });\n * ```\n */\n async create(\n params: CreateSubscriptionParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<CreatedSubscription>> {\n return this.httpClient.post(\"/subscriptions\", params, options);\n }\n\n /**\n * Get the active subscription for a customer\n *\n * @example\n * ```typescript\n * const sub = await commet.subscriptions.get('user_123');\n * ```\n */\n async get(\n externalId: string,\n ): Promise<ApiResponse<ActiveSubscription | null>> {\n return this.httpClient.get(\"/subscriptions/active\", { externalId });\n }\n\n /**\n * Cancel a subscription\n *\n * @example\n * ```typescript\n * await commet.subscriptions.cancel({\n * subscriptionId: 'sub_xxx',\n * reason: 'switched_to_competitor'\n * });\n * ```\n */\n async cancel(\n params: CancelParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Subscription>> {\n return this.httpClient.post(\n `/subscriptions/${params.subscriptionId}/cancel`,\n params || {},\n options,\n );\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n EventID,\n GeneratedFeatureCode,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface UsageEvent {\n id: EventID;\n organizationId: string;\n customerId: CustomerID;\n feature: string;\n idempotencyKey?: string;\n ts: string;\n properties?: UsageEventProperty[];\n createdAt: string;\n}\n\nexport interface UsageEventProperty {\n id: string;\n usageEventId: EventID;\n property: string;\n value: string;\n createdAt: string;\n}\n\nexport interface BatchResult<T> {\n successful: T[];\n failed: Array<{\n index: number;\n error: string;\n data: TrackParams;\n }>;\n}\n\nexport interface TrackParams {\n feature: GeneratedFeatureCode;\n customerId?: CustomerID;\n externalId?: string;\n idempotencyKey?: string;\n value?: number;\n timestamp?: string;\n properties?: Record<string, string>;\n}\n\n/**\n * Usage resource - Track consumption events for usage-based billing\n */\nexport class UsageResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Track a usage event\n *\n * @example\n * ```typescript\n * await commet.usage.track({\n * externalId: 'user_123',\n * feature: 'api_call',\n * value: 1,\n * idempotencyKey: `evt_${requestId}`,\n * properties: { endpoint: '/users', method: 'GET' }\n * });\n * ```\n */\n async track(\n params: TrackParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<UsageEvent>> {\n const eventData = {\n feature: params.feature,\n customerId: params.customerId,\n externalId: params.externalId,\n idempotencyKey: params.idempotencyKey,\n value: params.value,\n timestamp: params.timestamp || new Date().toISOString(),\n properties: params.properties\n ? Object.entries(params.properties).map(([property, value]) => ({\n property,\n value,\n }))\n : undefined,\n };\n\n return this.httpClient.post(\"/usage/events\", eventData, options);\n }\n\n /**\n * Track multiple usage events in a batch\n *\n * @example\n * ```typescript\n * await commet.usage.trackBatch({\n * events: [\n * { externalId: 'user_123', feature: 'api_call', value: 1, idempotencyKey: 'evt_1' },\n * { externalId: 'user_456', feature: 'api_call', value: 5, idempotencyKey: 'evt_2' }\n * ]\n * });\n * ```\n */\n async trackBatch(\n params: { events: TrackParams[] },\n options?: RequestOptions,\n ): Promise<ApiResponse<BatchResult<UsageEvent>>> {\n const events = params.events.map((event) => ({\n feature: event.feature,\n customerId: event.customerId,\n externalId: event.externalId,\n idempotencyKey: event.idempotencyKey,\n value: event.value,\n timestamp: event.timestamp || new Date().toISOString(),\n properties: event.properties\n ? Object.entries(event.properties).map(([property, value]) => ({\n property,\n value,\n }))\n : undefined,\n }));\n\n return this.httpClient.post(\"/usage/events/batch\", { events }, options);\n }\n}\n","import crypto from \"node:crypto\";\n\n/**\n * Webhook payload structure from Commet\n */\nexport interface WebhookPayload {\n event: WebhookEvent;\n timestamp: string;\n organizationId: string;\n data: WebhookData;\n}\n\n/**\n * Webhook data structure (subscription-related fields)\n */\nexport interface WebhookData {\n id?: string;\n publicId?: string;\n subscriptionId?: string;\n customerId?: string;\n externalId?: string;\n status?: string;\n name?: string;\n canceledAt?: string;\n [key: string]: unknown;\n}\n\n/**\n * Supported webhook events\n */\nexport type WebhookEvent =\n | \"subscription.created\"\n | \"subscription.activated\"\n | \"subscription.canceled\"\n | \"subscription.updated\";\n\nexport interface VerifyParams {\n payload: string;\n signature: string | null;\n secret: string;\n}\n\nexport interface GenerateSignatureParams {\n payload: string;\n secret: string;\n}\n\nexport interface VerifyAndParseParams {\n rawBody: string;\n signature: string | null;\n secret: string;\n}\n\n/**\n * Webhooks resource for signature verification\n */\nexport class Webhooks {\n /**\n * Verify HMAC-SHA256 webhook signature\n *\n * Use this method to verify that webhooks are authentically from Commet.\n * The signature is included in the `X-Commet-Signature` header.\n *\n * @param payload - Raw request body as string (IMPORTANT: Do not parse JSON first)\n * @param signature - Value from X-Commet-Signature header\n * @param secret - Your webhook secret from Commet dashboard\n * @returns true if signature is valid, false otherwise\n *\n * @example\n * ```typescript\n * // Next.js API route example\n * export async function POST(request: Request) {\n * const rawBody = await request.text();\n * const signature = request.headers.get('x-commet-signature');\n *\n * const isValid = commet.webhooks.verify(\n * rawBody,\n * signature,\n * process.env.COMMET_WEBHOOK_SECRET\n * );\n *\n * if (!isValid) {\n * return new Response('Invalid signature', { status: 401 });\n * }\n *\n * const payload = JSON.parse(rawBody);\n * // Handle webhook event...\n * }\n * ```\n */\n verify(params: VerifyParams): boolean {\n const { payload, signature, secret } = params;\n\n if (!signature || !secret || !payload) {\n return false;\n }\n\n try {\n const expectedSignature = this.generateSignature({ payload, secret });\n\n // Use timing-safe comparison to prevent timing attacks\n return crypto.timingSafeEqual(\n Buffer.from(signature, \"hex\"),\n Buffer.from(expectedSignature, \"hex\"),\n );\n } catch (error) {\n // timingSafeEqual throws if lengths don't match\n return false;\n }\n }\n\n /**\n * Generate HMAC-SHA256 signature (internal use)\n * @internal\n */\n private generateSignature(params: GenerateSignatureParams): string {\n const { payload, secret } = params;\n return crypto.createHmac(\"sha256\", secret).update(payload).digest(\"hex\");\n }\n\n /**\n * Parse and verify webhook payload in one step\n *\n * @example\n * ```typescript\n * const payload = commet.webhooks.verifyAndParse({\n * rawBody,\n * signature,\n * secret: process.env.COMMET_WEBHOOK_SECRET\n * });\n *\n * if (!payload) {\n * return new Response('Invalid signature', { status: 401 });\n * }\n *\n * // payload is typed and validated\n * if (payload.event === 'subscription.activated') {\n * // Handle activation...\n * }\n * ```\n */\n verifyAndParse(params: VerifyAndParseParams): WebhookPayload | null {\n const { rawBody, signature, secret } = params;\n\n if (!this.verify({ payload: rawBody, signature, secret })) {\n return null;\n }\n\n try {\n return JSON.parse(params.rawBody) as WebhookPayload;\n } catch {\n return null;\n }\n }\n}\n","export type Environment = \"sandbox\" | \"production\";\n\nexport type CommetConfig = {\n apiKey: string;\n environment?: Environment;\n debug?: boolean;\n timeout?: number;\n retries?: number;\n};\n\n// API Response types\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n code?: string;\n message?: string;\n details?: unknown;\n // Pagination fields (optional, included for list endpoints)\n hasMore?: boolean;\n nextCursor?: string;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n hasMore: boolean;\n nextCursor?: string;\n totalCount?: number;\n}\n\nexport interface PaginatedList<T> extends PaginatedResponse<T> {\n next(): Promise<PaginatedList<T>>;\n all(): Promise<T[]>;\n}\n\n// Error types\nexport class CommetError extends Error {\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommetError\";\n }\n}\n\nexport class CommetAPIError extends CommetError {\n constructor(\n message: string,\n public statusCode: number,\n public code?: string,\n public details?: unknown,\n ) {\n super(message, code, statusCode, details);\n this.name = \"CommetAPIError\";\n }\n}\n\nexport class CommetValidationError extends CommetError {\n constructor(\n message: string,\n public validationErrors: Record<string, string[]>,\n ) {\n super(message);\n this.name = \"CommetValidationError\";\n }\n}\n\nexport type CustomerID = `cus_${string}`;\nexport type AgreementID = `agr_${string}`;\nexport type InvoiceID = `inv_${string}`;\nexport type PhaseID = `phs_${string}`;\nexport type ItemID = `itm_${string}`;\nexport type ProductID = `prd_${string}`;\nexport type EventID = `evt_${string}`;\nexport type WebhookID = `wh_${string}`;\n\n// Currency enum\nexport type Currency =\n | \"USD\"\n | \"EUR\"\n | \"GBP\"\n | \"CAD\"\n | \"AUD\"\n | \"JPY\"\n | \"ARS\"\n | \"BRL\"\n | \"MXN\"\n | \"CLP\";\n\n// Common parameters\nexport interface ListParams extends Record<string, unknown> {\n limit?: number;\n cursor?: string;\n startDate?: string;\n endDate?: string;\n}\n\nexport interface RetrieveOptions {\n expand?: string[];\n}\n\n// Request options\nexport interface RequestOptions {\n idempotencyKey?: string;\n timeout?: number;\n}\n\n/**\n * Generated types interface - augmented by CLI after 'commet pull'\n *\n * This interface gets filled by module augmentation when you run `commet pull`.\n * The CLI generates a .commet/types.d.ts file that augments this interface with your\n * organization's specific feature codes, seat types, and plan codes.\n *\n * @example\n * // After running `commet pull`, TypeScript will automatically know your types:\n * await commet.usage.track({\n * feature: 'api_calls', // Autocomplete works!\n * externalId: 'user_123'\n * });\n */\n\n// biome-ignore lint/suspicious/noEmptyInterface: augmented by CLI-generated .commet/types.d.ts\nexport interface CommetGeneratedTypes {}\n\nexport type GeneratedSeatType = CommetGeneratedTypes extends {\n seatType: infer T;\n}\n ? T\n : string;\n\nexport type GeneratedPlanCode = CommetGeneratedTypes extends {\n planCode: infer T;\n}\n ? T\n : string;\n\nexport type GeneratedFeatureCode = CommetGeneratedTypes extends {\n featureCode: infer T;\n}\n ? T\n : string;\n","import type {\n ApiResponse,\n CommetConfig,\n Environment,\n RequestOptions,\n} from \"../types/common\";\nimport { CommetAPIError, CommetValidationError } from \"../types/common\";\n\nexport interface RetryConfig {\n maxRetries: number;\n baseDelay: number;\n maxDelay: number;\n retryableStatusCodes: number[];\n}\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 1000, // 1s\n maxDelay: 8000, // 8s\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\nexport class CommetHTTPClient {\n private config: CommetConfig;\n private environment: Environment;\n private retryConfig: RetryConfig;\n\n constructor(config: CommetConfig, environment: Environment) {\n this.config = config;\n this.environment = environment;\n this.retryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n maxRetries: config.retries ?? DEFAULT_RETRY_CONFIG.maxRetries,\n };\n }\n\n async get<T = unknown>(\n endpoint: string,\n params?: Record<string, unknown>,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"GET\", endpoint, undefined, options, params);\n }\n\n async post<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"POST\", endpoint, data, options);\n }\n\n async put<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"PUT\", endpoint, data, options);\n }\n\n async delete<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"DELETE\", endpoint, data, options);\n }\n\n /**\n * Core request method with retry logic\n */\n private async request<T = unknown>(\n method: string,\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n params?: Record<string, unknown>,\n ): Promise<ApiResponse<T>> {\n const url = this.buildURL(endpoint, params);\n return this.executeRequest(method, url, data, options);\n }\n\n /**\n * Execute real API request with retry logic\n */\n private async executeRequest<T = unknown>(\n method: string,\n url: string,\n data?: unknown,\n options?: RequestOptions,\n attempt = 1,\n ): Promise<ApiResponse<T>> {\n try {\n const headers: Record<string, string> = {\n \"x-api-key\": this.config.apiKey,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"commet/0.1.0\",\n };\n\n if (options?.idempotencyKey) {\n headers[\"Idempotency-Key\"] = options.idempotencyKey;\n } else if (method === \"POST\" && data) {\n headers[\"Idempotency-Key\"] = this.generateIdempotencyKey();\n }\n\n const requestConfig: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(\n options?.timeout ?? this.config.timeout ?? 30000,\n ),\n };\n\n if (data) {\n requestConfig.body = JSON.stringify(data);\n }\n\n if (this.config.debug) {\n console.log(`[Commet SDK] ${method} ${url}`);\n if (data) {\n console.log(\"Request data:\", JSON.stringify(data, null, 2));\n }\n }\n\n const response = await fetch(url, requestConfig);\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Response status: ${response.status} ${response.statusText}`,\n );\n }\n\n let responseData: unknown;\n let responseText: string;\n\n try {\n responseData = await response.json();\n responseText = \"\";\n } catch (jsonError) {\n try {\n responseText = await response.text();\n } catch (textError) {\n responseText = \"Failed to read response body\";\n }\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Failed to parse JSON response:\",\n responseText,\n );\n }\n\n // For 404 errors with invalid JSON, return a graceful response\n // This handles cases like HTML error pages or empty responses\n if (response.status === 404) {\n return {\n success: false,\n code: \"not_found\",\n message: \"Resource not found\",\n } as ApiResponse<T>;\n }\n\n throw new CommetAPIError(\n `Invalid JSON response: ${response.status} ${response.statusText}`,\n response.status,\n \"INVALID_JSON\",\n { responseText },\n );\n }\n\n if (!response.ok) {\n // Check if we should retry\n if (\n attempt <= this.retryConfig.maxRetries &&\n this.retryConfig.retryableStatusCodes.includes(response.status)\n ) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Retrying in ${delay}ms (attempt ${attempt}/${this.retryConfig.maxRetries})`,\n );\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n\n // Log error response for debugging\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Error response:\",\n JSON.stringify(responseData, null, 2),\n );\n }\n\n // Type guard for error response\n const isErrorResponse = (\n data: unknown,\n ): data is {\n message?: string;\n code?: string;\n details?: unknown;\n } => {\n return typeof data === \"object\" && data !== null;\n };\n\n const errorData = isErrorResponse(responseData) ? responseData : {};\n\n // Handle validation errors (new normalized shape)\n if (\n errorData.code === \"validation_error\" &&\n Array.isArray(errorData.details)\n ) {\n const errors: Record<string, string[]> = {};\n for (const detail of errorData.details as Array<{\n field: string;\n message: string;\n }>) {\n if (!errors[detail.field]) errors[detail.field] = [];\n errors[detail.field].push(detail.message);\n }\n throw new CommetValidationError(\n errorData.message || \"Validation failed\",\n errors,\n );\n }\n\n throw new CommetAPIError(\n errorData.message || `Request failed with status ${response.status}`,\n response.status,\n errorData.code,\n errorData.details,\n );\n }\n\n if (this.config.debug) {\n console.log(\"[Commet SDK] Response:\", responseData);\n }\n\n return responseData as ApiResponse<T>;\n } catch (error) {\n // Handle network errors and timeouts\n if (error instanceof TypeError && error.message.includes(\"fetch\")) {\n if (attempt <= this.retryConfig.maxRetries) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(`[Commet SDK] Network error, retrying in ${delay}ms`);\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Get base URL based on environment\n */\n private getBaseURL(): string {\n return this.environment === \"production\"\n ? \"https://commet.co\"\n : \"https://sandbox.commet.co\";\n }\n\n /**\n * Build full URL from endpoint and params\n */\n private buildURL(endpoint: string, params?: Record<string, unknown>): string {\n const baseURL = this.getBaseURL();\n\n // Construct full path with /api prefix\n const normalizedEndpoint = endpoint.startsWith(\"/\")\n ? endpoint\n : `/${endpoint}`;\n const fullPath = `/api${normalizedEndpoint}`;\n\n // Debug logging\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Building URL - baseURL: ${baseURL}, endpoint: ${endpoint}, fullPath: ${fullPath}`,\n );\n }\n\n const url = new URL(fullPath, baseURL);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n }\n }\n\n const finalUrl = url.toString();\n\n // Debug final URL\n if (this.config.debug) {\n console.log(`[Commet SDK] Final URL: ${finalUrl}`);\n }\n\n return finalUrl;\n }\n\n /**\n * Generate idempotency key\n */\n private generateIdempotencyKey(): string {\n // Generate UUID-like key for idempotency\n return `sdk_${Date.now()}_${Math.random().toString(36).substring(2)}`;\n }\n\n /**\n * Sleep for specified milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { CustomerContext } from \"./customer\";\nimport { CreditPacksResource } from \"./resources/credit-packs\";\nimport { CustomersResource } from \"./resources/customers\";\nimport { FeaturesResource } from \"./resources/features\";\nimport { PlansResource } from \"./resources/plans\";\nimport { PortalResource } from \"./resources/portal\";\nimport { SeatsResource } from \"./resources/seats\";\nimport { SubscriptionsResource } from \"./resources/subscriptions\";\nimport { UsageResource } from \"./resources/usage\";\nimport { Webhooks } from \"./resources/webhooks\";\nimport type { CommetConfig, Environment } from \"./types/common\";\nimport { CommetHTTPClient } from \"./utils/http\";\n\n/**\n * Main Commet SDK client\n */\nexport class Commet {\n private httpClient: CommetHTTPClient;\n private environment: Environment;\n\n public readonly customers: CustomersResource;\n public readonly creditPacks: CreditPacksResource;\n public readonly plans: PlansResource;\n public readonly usage: UsageResource;\n public readonly seats: SeatsResource;\n public readonly subscriptions: SubscriptionsResource;\n public readonly portal: PortalResource;\n public readonly features: FeaturesResource;\n public readonly webhooks: Webhooks;\n\n constructor(config: CommetConfig) {\n if (!config.apiKey) {\n throw new Error(\"Commet SDK: API key is required\");\n }\n\n if (!config.apiKey.startsWith(\"ck_\")) {\n throw new Error(\n \"Commet SDK: Invalid API key format. Expected format: ck_xxx...\",\n );\n }\n\n // Default to sandbox for safety\n this.environment = config.environment || \"sandbox\";\n\n this.httpClient = new CommetHTTPClient(config, this.environment);\n this.customers = new CustomersResource(this.httpClient);\n this.creditPacks = new CreditPacksResource(this.httpClient);\n this.plans = new PlansResource(this.httpClient);\n this.usage = new UsageResource(this.httpClient);\n this.seats = new SeatsResource(this.httpClient);\n this.subscriptions = new SubscriptionsResource(this.httpClient);\n this.portal = new PortalResource(this.httpClient);\n this.features = new FeaturesResource(this.httpClient);\n this.webhooks = new Webhooks();\n\n if (config.debug) {\n console.log(`[Commet SDK] Initialized in ${this.environment} mode`);\n console.log(\"API Key:\", `${config.apiKey.substring(0, 12)}...`);\n const baseURL =\n this.environment === \"production\"\n ? \"https://commet.co\"\n : \"https://sandbox.commet.co\";\n console.log(\"Base URL:\", baseURL);\n }\n }\n\n /**\n * Create a customer-scoped context for cleaner API usage\n *\n * @example\n * ```typescript\n * const customer = commet.customer(\"user_123\");\n *\n * // All operations are now scoped to this customer\n * const seats = await customer.features.get(\"team_members\");\n * await customer.seats.add(\"member\");\n * await customer.usage.track(\"api_call\");\n * ```\n */\n customer(externalId: string): CustomerContext {\n return new CustomerContext(externalId, {\n features: this.features,\n seats: this.seats,\n usage: this.usage,\n subscriptions: this.subscriptions,\n portal: this.portal,\n });\n }\n\n getEnvironment(): Environment {\n return this.environment;\n }\n\n isSandbox(): boolean {\n return this.environment === \"sandbox\";\n }\n\n isProduction(): boolean {\n return this.environment === \"production\";\n }\n}\n","import type { Environment } from \"../types/common\";\n\n/**\n * Check if environment is sandbox\n */\nexport function isSandbox(environment: Environment): boolean {\n return environment === \"sandbox\";\n}\n\n/**\n * Check if environment is production\n */\nexport function isProduction(environment: Environment): boolean {\n return environment === \"production\";\n}\n","/**\n * Commet SDK - Billing and usage tracking for SaaS\n */\nexport { Commet } from \"./client\";\nexport { CustomerContext } from \"./customer\";\n\n// Type exports\nexport type {\n CommetConfig,\n CommetGeneratedTypes,\n GeneratedSeatType,\n GeneratedPlanCode,\n GeneratedFeatureCode,\n Environment,\n ApiResponse,\n PaginatedResponse,\n PaginatedList,\n Currency,\n CustomerID,\n EventID,\n RequestOptions,\n} from \"./types/common\";\n\n// Error exports\nexport {\n CommetError,\n CommetAPIError,\n CommetValidationError,\n} from \"./types/common\";\n\n// Customers\nexport type {\n Customer,\n CustomerAddress,\n CreateParams as CreateCustomerParams,\n UpdateParams as UpdateCustomerParams,\n ListCustomersParams,\n BatchResult as CustomersBatchResult,\n} from \"./resources/customers\";\n\n// Usage\nexport type {\n UsageEvent,\n UsageEventProperty,\n TrackParams,\n BatchResult as UsageBatchResult,\n} from \"./resources/usage\";\n\n// Seats\nexport type {\n SeatEvent,\n SeatBalance,\n AddParams as AddSeatsParams,\n RemoveParams as RemoveSeatsParams,\n SetParams as SetSeatsParams,\n SetAllParams as SetAllSeatsParams,\n GetBalanceParams,\n GetAllBalancesParams,\n} from \"./resources/seats\";\n\n// Credit Packs\nexport type { CreditPack } from \"./resources/credit-packs\";\n\n// Plans\nexport type {\n Plan,\n PlanDetail,\n PlanPrice,\n PlanFeature,\n PlanID,\n BillingInterval,\n FeatureType,\n ListPlansParams,\n} from \"./resources/plans\";\n\n// Subscriptions\nexport type {\n CreatedSubscription,\n Subscription,\n ActiveSubscription,\n SubscriptionStatus,\n FeatureSummary,\n CreateSubscriptionParams,\n CancelParams,\n} from \"./resources/subscriptions\";\n\n// Portal\nexport type { PortalAccess, GetUrlParams } from \"./resources/portal\";\n\n// Features\nexport type {\n FeatureAccess,\n CanUseResult,\n CheckResult,\n GetFeatureParams,\n CheckFeatureParams,\n CanUseFeatureParams,\n} from \"./resources/features\";\n\n// Webhooks\nexport { Webhooks } from \"./resources/webhooks\";\nexport type {\n WebhookPayload,\n WebhookData,\n WebhookEvent,\n} from \"./resources/webhooks\";\n\n// Utility exports\nexport { isSandbox, isProduction } from \"./utils/environment\";\n\n// Default export\nimport { Commet } from \"./client\";\nexport default Commet;\n"],"mappings":"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","names":["data"]}
1
+ {"version":3,"sources":["../src/customer.ts","../src/resources/credit-packs.ts","../src/resources/customers.ts","../src/resources/features.ts","../src/resources/plans.ts","../src/resources/portal.ts","../src/resources/seats.ts","../src/resources/subscriptions.ts","../src/resources/usage.ts","../src/resources/webhooks.ts","../src/types/common.ts","../src/utils/http.ts","../src/client.ts","../src/utils/environment.ts","../src/index.ts"],"sourcesContent":["import type { FeaturesResource } from \"./resources/features\";\nimport type { PortalResource } from \"./resources/portal\";\nimport type { SeatsResource } from \"./resources/seats\";\nimport type { SubscriptionsResource } from \"./resources/subscriptions\";\nimport type { UsageResource } from \"./resources/usage\";\nimport type { RequestOptions } from \"./types/common\";\n\n/**\n * Customer-scoped API context\n *\n * Provides a cleaner API where you don't have to pass externalId\n * on every call. All operations are scoped to a specific customer.\n *\n * @example\n * ```typescript\n * const customer = commet.customer(\"user_123\");\n *\n * // All operations are now scoped to this customer\n * const seats = await customer.features.get(\"team_members\");\n * await customer.seats.add(\"member\");\n * await customer.usage.track(\"api_call\");\n * ```\n */\nexport class CustomerContext {\n private readonly externalId: string;\n private readonly featuresResource: FeaturesResource;\n private readonly seatsResource: SeatsResource;\n private readonly usageResource: UsageResource;\n private readonly subscriptionsResource: SubscriptionsResource;\n private readonly portalResource: PortalResource;\n\n constructor(\n externalId: string,\n resources: {\n features: FeaturesResource;\n seats: SeatsResource;\n usage: UsageResource;\n subscriptions: SubscriptionsResource;\n portal: PortalResource;\n },\n ) {\n this.externalId = externalId;\n this.featuresResource = resources.features;\n this.seatsResource = resources.seats;\n this.usageResource = resources.usage;\n this.subscriptionsResource = resources.subscriptions;\n this.portalResource = resources.portal;\n }\n\n /**\n * Feature access methods - delegates to FeaturesResource\n */\n features = {\n get: (code: string, options?: RequestOptions) =>\n this.featuresResource.get({ code, externalId: this.externalId }, options),\n\n check: (code: string, options?: RequestOptions) =>\n this.featuresResource.check(\n { code, externalId: this.externalId },\n options,\n ),\n\n canUse: (code: string, options?: RequestOptions) =>\n this.featuresResource.canUse(\n { code, externalId: this.externalId },\n options,\n ),\n\n list: (options?: RequestOptions) =>\n this.featuresResource.list(this.externalId, options),\n };\n\n /**\n * Seat management methods - delegates to SeatsResource\n */\n seats = {\n add: (seatType: string, count = 1, options?: RequestOptions) =>\n this.seatsResource.add(\n { externalId: this.externalId, seatType, count },\n options,\n ),\n\n remove: (seatType: string, count = 1, options?: RequestOptions) =>\n this.seatsResource.remove(\n { externalId: this.externalId, seatType, count },\n options,\n ),\n\n set: (seatType: string, count: number, options?: RequestOptions) =>\n this.seatsResource.set(\n { externalId: this.externalId, seatType, count },\n options,\n ),\n\n getBalance: (seatType: string) =>\n this.seatsResource.getBalance({ externalId: this.externalId, seatType }),\n };\n\n /**\n * Usage tracking methods - delegates to UsageResource\n */\n usage = {\n track: (\n feature: string,\n value?: number,\n properties?: Record<string, string>,\n options?: RequestOptions,\n ) =>\n this.usageResource.track(\n { externalId: this.externalId, feature, value, properties },\n options,\n ),\n };\n\n /**\n * Subscription methods - delegates to SubscriptionsResource\n */\n subscription = {\n get: () => this.subscriptionsResource.get(this.externalId),\n };\n\n /**\n * Portal methods - delegates to PortalResource\n */\n portal = {\n getUrl: (options?: RequestOptions) =>\n this.portalResource.getUrl({ externalId: this.externalId }, options),\n };\n}\n","import type { ApiResponse } from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface CreditPack {\n id: string;\n name: string;\n description: string | null;\n credits: number;\n price: number;\n currency: string;\n}\n\n/**\n * Credit Packs resource for listing available credit packs\n */\nexport class CreditPacksResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * List all active credit packs\n *\n * @example\n * ```typescript\n * const packs = await commet.creditPacks.list();\n * console.log(packs.data); // [{ id: \"cp_xxx\", name: \"100 Credits\", ... }]\n * ```\n */\n async list(): Promise<ApiResponse<CreditPack[]>> {\n return this.httpClient.get(\"/credit-packs\");\n }\n}\n","import type {\n ApiResponse,\n ListParams as BaseListParams,\n CustomerID,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface Customer {\n id: CustomerID;\n organizationId: string;\n externalId?: string;\n fullName?: string;\n domain?: string;\n website?: string;\n billingEmail: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CustomerAddress {\n line1: string;\n line2?: string;\n city: string;\n state?: string;\n postalCode: string;\n country: string; // ISO-2\n}\n\nexport interface CreateParams {\n email: string; // billingEmail - the only required field\n externalId?: string;\n fullName?: string;\n domain?: string;\n website?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n metadata?: Record<string, unknown>;\n address?: CustomerAddress;\n}\n\nexport interface UpdateParams {\n customerId: CustomerID;\n externalId?: string;\n email?: string;\n fullName?: string;\n domain?: string;\n website?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ListCustomersParams extends BaseListParams {\n externalId?: string;\n isActive?: boolean;\n search?: string;\n}\n\nexport interface BatchResult {\n successful: Customer[];\n failed: Array<{\n index: number;\n error: string;\n data: CreateParams;\n }>;\n}\n\n/**\n * Customers resource - Manage your customers\n */\nexport class CustomersResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Create a customer (idempotent with externalId)\n */\n async create(\n params: CreateParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.post(\n \"/customers\",\n {\n billingEmail: params.email,\n externalId: params.externalId,\n fullName: params.fullName,\n domain: params.domain,\n website: params.website,\n timezone: params.timezone,\n language: params.language,\n industry: params.industry,\n metadata: params.metadata,\n address: params.address,\n },\n options,\n );\n }\n\n /**\n * Create multiple customers in batch\n */\n async createBatch(\n params: { customers: CreateParams[] },\n options?: RequestOptions,\n ): Promise<ApiResponse<BatchResult>> {\n const customers = params.customers.map((c) => ({\n billingEmail: c.email,\n externalId: c.externalId,\n fullName: c.fullName,\n domain: c.domain,\n website: c.website,\n timezone: c.timezone,\n language: c.language,\n industry: c.industry,\n metadata: c.metadata,\n address: c.address,\n }));\n return this.httpClient.post(\"/customers/batch\", { customers }, options);\n }\n\n /**\n * Get a customer by ID\n */\n async get(customerId: CustomerID): Promise<ApiResponse<Customer>> {\n return this.httpClient.get(`/customers/${customerId}`);\n }\n\n /**\n * Update a customer\n */\n async update(\n params: UpdateParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(\n `/customers/${params.customerId}`,\n {\n billingEmail: params.email,\n externalId: params.externalId,\n fullName: params.fullName,\n domain: params.domain,\n website: params.website,\n timezone: params.timezone,\n language: params.language,\n industry: params.industry,\n metadata: params.metadata,\n },\n options,\n );\n }\n\n /**\n * List customers with optional filters\n */\n async list(params?: ListCustomersParams): Promise<ApiResponse<Customer[]>> {\n return this.httpClient.get(\"/customers\", params as Record<string, unknown>);\n }\n\n /**\n * Archive a customer\n */\n async archive(\n customerId: CustomerID,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(\n `/customers/${customerId}`,\n { isActive: false },\n options,\n );\n }\n}\n","import type {\n ApiResponse,\n GeneratedFeatureCode,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface FeatureParams {\n externalId: string;\n code: GeneratedFeatureCode;\n}\n\nexport type GetFeatureParams = FeatureParams;\nexport type CheckFeatureParams = FeatureParams;\nexport type CanUseFeatureParams = FeatureParams;\n\nexport interface FeatureAccess {\n code: string;\n name: string;\n type: \"boolean\" | \"metered\" | \"seats\";\n allowed: boolean;\n // For boolean features\n enabled?: boolean;\n // For metered/seats features\n current?: number;\n included?: number;\n remaining?: number;\n overage?: number;\n overageUnitPrice?: number;\n unlimited?: boolean;\n overageEnabled?: boolean;\n}\n\nexport interface CanUseResult {\n allowed: boolean;\n willBeCharged: boolean;\n reason?: string;\n}\n\nexport interface CheckResult {\n allowed: boolean;\n}\n\n/**\n * Features resource for checking feature access and usage\n *\n * Provides a clean API to check if a customer can use a feature\n * without having to manually parse subscription data.\n */\nexport class FeaturesResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Get detailed feature access/usage for a customer\n *\n * @example\n * ```typescript\n * const seats = await commet.features.get({ code: \"team_members\", externalId: \"user_123\" });\n * console.log(seats.current, seats.included, seats.remaining);\n * ```\n */\n async get(\n params: GetFeatureParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<FeatureAccess>> {\n const { code, externalId } = params;\n\n return this.httpClient.get(\n `/features/${code}`,\n { externalId: externalId },\n options,\n );\n }\n\n /**\n * Check if a boolean feature is enabled for a customer\n *\n * @example\n * ```typescript\n * const { allowed } = await commet.features.check({\n * code: \"custom_branding\",\n * externalId: \"user_123\"\n * });\n * if (!allowed) redirect(\"/upgrade\");\n * ```\n */\n async check(\n params: CheckFeatureParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<CheckResult>> {\n const { code, externalId } = params;\n\n const result = await this.httpClient.get<FeatureAccess>(\n `/features/${code}`,\n { externalId: externalId },\n options,\n );\n\n if (!result.success || !result.data) {\n return {\n success: false,\n data: { allowed: false },\n message: result.message,\n };\n }\n\n return {\n success: true,\n data: { allowed: result.data.allowed },\n message: result.message,\n };\n }\n\n /**\n * Check if customer can use one more unit of a feature\n *\n * Returns whether the customer can add one more (allowed)\n * and whether they'll be charged extra (willBeCharged).\n *\n * @example\n * ```typescript\n * const { allowed, willBeCharged } = await commet.features.canUse({\n * code: \"team_members\",\n * externalId: \"user_123\"\n * });\n *\n * if (!allowed) {\n * return { error: \"Upgrade to add more members\" };\n * }\n *\n * if (willBeCharged) {\n * // Show confirmation: \"This will cost $10/month extra\"\n * }\n * ```\n */\n async canUse(\n params: CanUseFeatureParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<CanUseResult>> {\n const { code, externalId } = params;\n\n return this.httpClient.get(\n `/features/${code}`,\n { externalId: externalId, action: \"canUse\" },\n options,\n );\n }\n\n /**\n * List all features for a customer's active subscription\n *\n * @example\n * ```typescript\n * const features = await commet.features.list({ externalId: \"user_123\" });\n * for (const feature of features) {\n * console.log(feature.code, feature.allowed);\n * }\n * ```\n */\n async list(\n externalId: string,\n options?: RequestOptions,\n ): Promise<ApiResponse<FeatureAccess[]>> {\n return this.httpClient.get(\"/features\", { externalId }, options);\n }\n}\n","import type {\n ApiResponse,\n GeneratedPlanCode,\n ListParams,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport type PlanID = `plan_${string}`;\nexport type BillingInterval = \"monthly\" | \"quarterly\" | \"yearly\";\nexport type FeatureType = \"boolean\" | \"metered\" | \"seats\";\n\nexport interface PlanPrice {\n billingInterval: BillingInterval;\n price: number; // in cents\n isDefault: boolean;\n trialDays: number;\n}\n\nexport interface PlanFeature {\n code: string;\n name: string;\n type: FeatureType;\n unitName: string | null;\n enabled?: boolean;\n includedAmount?: number;\n unlimited?: boolean;\n overageEnabled?: boolean;\n overageUnitPrice?: number;\n}\n\nexport interface Plan {\n id: PlanID;\n code: string;\n name: string;\n description: string | null;\n isPublic: boolean;\n isFree: boolean;\n isDefault: boolean;\n sortOrder: number;\n prices: PlanPrice[];\n features: PlanFeature[];\n createdAt: string;\n}\n\nexport interface PlanDetailPrice {\n billingInterval: BillingInterval;\n price: number;\n isDefault: boolean;\n trialDays: number;\n introOffer: {\n enabled: boolean;\n discountType: \"percentage\" | \"amount\" | null;\n discountValue: number | null;\n durationCycles: number | null;\n } | null;\n}\n\nexport interface PlanDetailFeature extends PlanFeature {\n overage: {\n enabled: boolean;\n model: \"per_unit\" | \"tiered\" | null;\n unitPrice: number | null;\n } | null;\n}\n\nexport interface PlanDetail {\n id: PlanID;\n code: string;\n name: string;\n description: string | null;\n isPublic: boolean;\n isDefault: boolean;\n sortOrder: number;\n prices: PlanDetailPrice[];\n features: PlanDetailFeature[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ListPlansParams extends ListParams {\n includePrivate?: boolean;\n}\n\n/**\n * Plans resource for listing available plans\n */\nexport class PlansResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * List all available plans\n *\n * @example\n * ```typescript\n * // List public plans\n * const plans = await commet.plans.list();\n *\n * // Include private plans\n * const allPlans = await commet.plans.list({ includePrivate: true });\n * ```\n */\n async list(params?: ListPlansParams): Promise<ApiResponse<Plan[]>> {\n return this.httpClient.get(\"/plans\", params);\n }\n\n /**\n * Get a specific plan by code\n *\n * @example\n * ```typescript\n * const plan = await commet.plans.get('pro');\n * console.log(plan.data.name); // \"Pro\"\n * console.log(plan.data.prices); // [{ billingInterval: 'monthly', price: 9900 }]\n * ```\n */\n async get(planCode: GeneratedPlanCode): Promise<ApiResponse<PlanDetail>> {\n return this.httpClient.get(`/plans/${planCode}`);\n }\n}\n","import type { ApiResponse, CustomerID, RequestOptions } from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface PortalAccess {\n success: boolean;\n message: string;\n portalUrl: string;\n}\n\ninterface GetUrlByCustomerId {\n customerId: CustomerID;\n email?: never;\n externalId?: never;\n}\n\ninterface GetUrlByExternalId {\n externalId: string;\n email?: never;\n customerId?: never;\n}\n\ninterface GetUrlByEmail {\n email: string;\n customerId?: never;\n externalId?: never;\n}\n\nexport type GetUrlParams =\n | GetUrlByCustomerId\n | GetUrlByExternalId\n | GetUrlByEmail;\n\n/**\n * Portal resource - Generate customer portal access\n */\nexport class PortalResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Get a portal URL\n *\n * @example\n * ```typescript\n * const portal = await commet.portal.getUrl({ externalId: 'user_123' });\n * ```\n */\n async getUrl(\n params: GetUrlParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<PortalAccess>> {\n return this.httpClient.post(\"/portal/request-access\", params, options);\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n GeneratedSeatType,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface SeatEvent {\n id: string;\n organizationId: string;\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n eventType: \"add\" | \"remove\" | \"set\";\n quantity: number;\n previousBalance?: number;\n newBalance: number;\n ts: string;\n createdAt: string;\n}\n\nexport interface SeatBalance {\n current: number;\n asOf: string;\n}\n\nexport interface AddParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface RemoveParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface SetParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface SetAllParams {\n customerId?: CustomerID;\n externalId?: string;\n seats: Record<string, number>;\n}\n\nexport interface GetBalanceParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n}\n\nexport interface GetAllBalancesParams {\n customerId?: CustomerID;\n externalId?: string;\n}\n\n/**\n * Seats resource - Manage seat-based licenses\n */\nexport class SeatsResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Add seats\n *\n * @example\n * ```typescript\n * await commet.seats.add({\n * externalId: 'user_123',\n * seatType: 'editor',\n * count: 5\n * });\n * ```\n */\n async add(\n params: AddParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.post(\"/seats\", params, options);\n }\n\n /**\n * Remove seats\n *\n * @example\n * ```typescript\n * await commet.seats.remove({\n * externalId: 'user_123',\n * seatType: 'editor',\n * count: 2\n * });\n * ```\n */\n async remove(\n params: RemoveParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.delete(\"/seats\", params, options);\n }\n\n /**\n * Set seats to a specific count\n *\n * @example\n * ```typescript\n * await commet.seats.set({\n * externalId: 'user_123',\n * seatType: 'editor',\n * count: 10\n * });\n * ```\n */\n async set(\n params: SetParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.put(\"/seats\", params, options);\n }\n\n /**\n * Set all seat types\n *\n * @example\n * ```typescript\n * await commet.seats.setAll({\n * externalId: 'user_123',\n * seats: { editor: 10, viewer: 50 }\n * });\n * ```\n */\n async setAll(\n params: SetAllParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent[]>> {\n return this.httpClient.put(\"/seats/bulk\", params, options);\n }\n\n /**\n * Get balance for a seat type\n *\n * @example\n * ```typescript\n * const balance = await commet.seats.getBalance({\n * externalId: 'user_123',\n * seatType: 'editor'\n * });\n * ```\n */\n async getBalance(\n params: GetBalanceParams,\n ): Promise<ApiResponse<SeatBalance>> {\n const { customerId, externalId, seatType } = params;\n\n return this.httpClient.get(\"/seats/balance\", {\n customerId: customerId,\n externalId: externalId,\n seatType: seatType,\n });\n }\n\n /**\n * Get all seat balances\n *\n * @example\n * ```typescript\n * const balances = await commet.seats.getAllBalances({\n * externalId: 'user_123'\n * });\n * ```\n */\n async getAllBalances(\n params: GetAllBalancesParams,\n ): Promise<ApiResponse<Record<string, SeatBalance>>> {\n const { customerId, externalId } = params;\n\n return this.httpClient.get(\"/seats/balances\", {\n customerId: customerId,\n externalId: externalId,\n });\n }\n}\n","import type {\n ApiResponse,\n GeneratedPlanCode,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\nimport type { BillingInterval } from \"./plans\";\n\nexport type SubscriptionStatus =\n | \"draft\"\n | \"pending_payment\"\n | \"trialing\"\n | \"active\"\n | \"paused\"\n | \"past_due\"\n | \"canceled\"\n | \"expired\";\n\nexport interface FeatureSummary {\n code: string;\n name: string;\n type: \"boolean\" | \"metered\" | \"seats\";\n enabled?: boolean;\n usage?: {\n current: number;\n included: number;\n overage: number;\n overageUnitPrice?: number;\n };\n}\n\nexport interface ActiveSubscription {\n id: string;\n customerId: string;\n plan: {\n id: string;\n name: string;\n basePrice: number;\n billingInterval: BillingInterval | null;\n };\n name: string;\n description: string | null;\n status: SubscriptionStatus;\n trialEndsAt: string | null;\n currentPeriod: {\n start: string;\n end: string;\n daysRemaining: number;\n };\n features: FeatureSummary[];\n startDate: string;\n endDate: string | null;\n billingDayOfMonth: number;\n nextBillingDate: string;\n checkoutUrl: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreatedSubscription {\n id: string;\n customerId: string;\n externalId: string;\n planId: string;\n planName: string;\n name: string;\n status: SubscriptionStatus;\n billingInterval: BillingInterval | null;\n trialEndsAt: string | null;\n startDate: string;\n endDate: string | null;\n currentPeriodStart: string | null;\n currentPeriodEnd: string | null;\n billingDayOfMonth: number;\n checkoutUrl: string | null;\n createdAt: string;\n updatedAt: string;\n introOfferEndsAt: string | null;\n introOfferDiscountType: \"percentage\" | \"amount\" | null;\n introOfferDiscountValue: number | null;\n}\n\nexport interface Subscription {\n id: string;\n customerId: string;\n planId: string;\n planName: string;\n name: string;\n description?: string;\n status: SubscriptionStatus;\n billingInterval: BillingInterval;\n trialEndsAt?: string;\n startDate: string;\n endDate?: string;\n currentPeriodStart?: string;\n currentPeriodEnd?: string;\n billingDayOfMonth: number;\n checkoutUrl?: string;\n createdAt: string;\n updatedAt: string;\n}\n\n// Customer identifier: mutually exclusive customerId or externalId\ntype CustomerIdentifier =\n | { customerId: string; externalId?: never }\n | { customerId?: never; externalId: string };\n\n// Plan identifier: use planCode (with autocomplete) or planId (legacy)\ntype PlanIdentifier =\n | { planCode: GeneratedPlanCode; planId?: never }\n | { planCode?: never; planId: string };\n\nexport type CreateSubscriptionParams = CustomerIdentifier &\n PlanIdentifier & {\n billingInterval?: BillingInterval;\n initialSeats?: Record<string, number>;\n skipTrial?: boolean;\n name?: string;\n startDate?: string;\n successUrl?: string;\n };\n\nexport interface CancelParams {\n subscriptionId: string;\n reason?: string;\n immediate?: boolean;\n}\n\n/**\n * Subscription resource for managing subscriptions (plan-first model)\n *\n * Each customer can only have ONE active subscription at a time.\n */\nexport class SubscriptionsResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n /**\n * Create a subscription with a plan\n *\n * @example\n * ```typescript\n * await commet.subscriptions.create({\n * externalId: 'user_123',\n * planCode: 'pro', // autocomplete works after `commet pull`\n * billingInterval: 'yearly',\n * initialSeats: { editor: 5 }\n * });\n * ```\n */\n async create(\n params: CreateSubscriptionParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<CreatedSubscription>> {\n return this.httpClient.post(\"/subscriptions\", params, options);\n }\n\n /**\n * Get the active subscription for a customer\n *\n * @example\n * ```typescript\n * const sub = await commet.subscriptions.get('user_123');\n * ```\n */\n async get(\n externalId: string,\n ): Promise<ApiResponse<ActiveSubscription | null>> {\n return this.httpClient.get(\"/subscriptions/active\", { externalId });\n }\n\n /**\n * Cancel a subscription\n *\n * @example\n * ```typescript\n * await commet.subscriptions.cancel({\n * subscriptionId: 'sub_xxx',\n * reason: 'switched_to_competitor'\n * });\n * ```\n */\n async cancel(\n params: CancelParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Subscription>> {\n return this.httpClient.post(\n `/subscriptions/${params.subscriptionId}/cancel`,\n params || {},\n options,\n );\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n EventID,\n GeneratedFeatureCode,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface UsageEvent {\n id: EventID;\n organizationId: string;\n customerId: CustomerID;\n feature: string;\n idempotencyKey?: string;\n ts: string;\n properties?: UsageEventProperty[];\n createdAt: string;\n}\n\nexport interface UsageEventProperty {\n id: string;\n usageEventId: EventID;\n property: string;\n value: string;\n createdAt: string;\n}\n\nexport interface BatchResult<T> {\n successful: T[];\n failed: Array<{\n index: number;\n error: string;\n data: TrackParams;\n }>;\n}\n\ninterface TrackBaseParams {\n feature: GeneratedFeatureCode;\n customerId?: CustomerID;\n externalId?: string;\n idempotencyKey?: string;\n timestamp?: string;\n properties?: Record<string, string>;\n}\n\nexport interface TrackUsageParams extends TrackBaseParams {\n value?: number;\n model?: never;\n}\n\nexport interface TrackModelTokensParams extends TrackBaseParams {\n model: string;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n value?: never;\n}\n\nexport type TrackParams = TrackUsageParams | TrackModelTokensParams;\n\nexport class UsageResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async track(\n params: TrackParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<UsageEvent>> {\n const eventData: Record<string, unknown> = {\n feature: params.feature,\n customerId: params.customerId,\n externalId: params.externalId,\n idempotencyKey: params.idempotencyKey,\n timestamp: params.timestamp || new Date().toISOString(),\n properties: params.properties\n ? Object.entries(params.properties).map(([property, value]) => ({\n property,\n value,\n }))\n : undefined,\n };\n\n if (\"model\" in params && params.model) {\n eventData.model = params.model;\n eventData.inputTokens = params.inputTokens;\n eventData.outputTokens = params.outputTokens;\n if (params.cacheReadTokens) {\n eventData.cacheReadTokens = params.cacheReadTokens;\n }\n if (params.cacheWriteTokens) {\n eventData.cacheWriteTokens = params.cacheWriteTokens;\n }\n } else {\n eventData.value = (params as TrackUsageParams).value;\n }\n\n return this.httpClient.post(\"/usage/events\", eventData, options);\n }\n\n async trackBatch(\n params: { events: TrackParams[] },\n options?: RequestOptions,\n ): Promise<ApiResponse<BatchResult<UsageEvent>>> {\n const events = params.events.map((event) => {\n const eventData: Record<string, unknown> = {\n feature: event.feature,\n customerId: event.customerId,\n externalId: event.externalId,\n idempotencyKey: event.idempotencyKey,\n timestamp: event.timestamp || new Date().toISOString(),\n properties: event.properties\n ? Object.entries(event.properties).map(([property, value]) => ({\n property,\n value,\n }))\n : undefined,\n };\n\n if (\"model\" in event && event.model) {\n eventData.model = event.model;\n eventData.inputTokens = event.inputTokens;\n eventData.outputTokens = event.outputTokens;\n if (event.cacheReadTokens) {\n eventData.cacheReadTokens = event.cacheReadTokens;\n }\n if (event.cacheWriteTokens) {\n eventData.cacheWriteTokens = event.cacheWriteTokens;\n }\n } else {\n eventData.value = (event as TrackUsageParams).value;\n }\n\n return eventData;\n });\n\n return this.httpClient.post(\"/usage/events/batch\", { events }, options);\n }\n}\n","import crypto from \"node:crypto\";\n\n/**\n * Webhook payload structure from Commet\n */\nexport interface WebhookPayload {\n event: WebhookEvent;\n timestamp: string;\n organizationId: string;\n data: WebhookData;\n}\n\n/**\n * Webhook data structure (subscription-related fields)\n */\nexport interface WebhookData {\n id?: string;\n publicId?: string;\n subscriptionId?: string;\n customerId?: string;\n externalId?: string;\n status?: string;\n name?: string;\n canceledAt?: string;\n [key: string]: unknown;\n}\n\n/**\n * Supported webhook events\n */\nexport type WebhookEvent =\n | \"subscription.created\"\n | \"subscription.activated\"\n | \"subscription.canceled\"\n | \"subscription.updated\";\n\nexport interface VerifyParams {\n payload: string;\n signature: string | null;\n secret: string;\n}\n\nexport interface GenerateSignatureParams {\n payload: string;\n secret: string;\n}\n\nexport interface VerifyAndParseParams {\n rawBody: string;\n signature: string | null;\n secret: string;\n}\n\n/**\n * Webhooks resource for signature verification\n */\nexport class Webhooks {\n /**\n * Verify HMAC-SHA256 webhook signature\n *\n * Use this method to verify that webhooks are authentically from Commet.\n * The signature is included in the `X-Commet-Signature` header.\n *\n * @param payload - Raw request body as string (IMPORTANT: Do not parse JSON first)\n * @param signature - Value from X-Commet-Signature header\n * @param secret - Your webhook secret from Commet dashboard\n * @returns true if signature is valid, false otherwise\n *\n * @example\n * ```typescript\n * // Next.js API route example\n * export async function POST(request: Request) {\n * const rawBody = await request.text();\n * const signature = request.headers.get('x-commet-signature');\n *\n * const isValid = commet.webhooks.verify(\n * rawBody,\n * signature,\n * process.env.COMMET_WEBHOOK_SECRET\n * );\n *\n * if (!isValid) {\n * return new Response('Invalid signature', { status: 401 });\n * }\n *\n * const payload = JSON.parse(rawBody);\n * // Handle webhook event...\n * }\n * ```\n */\n verify(params: VerifyParams): boolean {\n const { payload, signature, secret } = params;\n\n if (!signature || !secret || !payload) {\n return false;\n }\n\n try {\n const expectedSignature = this.generateSignature({ payload, secret });\n\n // Use timing-safe comparison to prevent timing attacks\n return crypto.timingSafeEqual(\n Buffer.from(signature, \"hex\"),\n Buffer.from(expectedSignature, \"hex\"),\n );\n } catch (error) {\n // timingSafeEqual throws if lengths don't match\n return false;\n }\n }\n\n /**\n * Generate HMAC-SHA256 signature (internal use)\n * @internal\n */\n private generateSignature(params: GenerateSignatureParams): string {\n const { payload, secret } = params;\n return crypto.createHmac(\"sha256\", secret).update(payload).digest(\"hex\");\n }\n\n /**\n * Parse and verify webhook payload in one step\n *\n * @example\n * ```typescript\n * const payload = commet.webhooks.verifyAndParse({\n * rawBody,\n * signature,\n * secret: process.env.COMMET_WEBHOOK_SECRET\n * });\n *\n * if (!payload) {\n * return new Response('Invalid signature', { status: 401 });\n * }\n *\n * // payload is typed and validated\n * if (payload.event === 'subscription.activated') {\n * // Handle activation...\n * }\n * ```\n */\n verifyAndParse(params: VerifyAndParseParams): WebhookPayload | null {\n const { rawBody, signature, secret } = params;\n\n if (!this.verify({ payload: rawBody, signature, secret })) {\n return null;\n }\n\n try {\n return JSON.parse(params.rawBody) as WebhookPayload;\n } catch {\n return null;\n }\n }\n}\n","export type Environment = \"sandbox\" | \"production\";\n\nexport type CommetConfig = {\n apiKey: string;\n environment?: Environment;\n debug?: boolean;\n timeout?: number;\n retries?: number;\n};\n\n// API Response types\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n code?: string;\n message?: string;\n details?: unknown;\n // Pagination fields (optional, included for list endpoints)\n hasMore?: boolean;\n nextCursor?: string;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n hasMore: boolean;\n nextCursor?: string;\n totalCount?: number;\n}\n\nexport interface PaginatedList<T> extends PaginatedResponse<T> {\n next(): Promise<PaginatedList<T>>;\n all(): Promise<T[]>;\n}\n\n// Error types\nexport class CommetError extends Error {\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommetError\";\n }\n}\n\nexport class CommetAPIError extends CommetError {\n constructor(\n message: string,\n public statusCode: number,\n public code?: string,\n public details?: unknown,\n ) {\n super(message, code, statusCode, details);\n this.name = \"CommetAPIError\";\n }\n}\n\nexport class CommetValidationError extends CommetError {\n constructor(\n message: string,\n public validationErrors: Record<string, string[]>,\n ) {\n super(message);\n this.name = \"CommetValidationError\";\n }\n}\n\nexport type CustomerID = `cus_${string}`;\nexport type AgreementID = `agr_${string}`;\nexport type InvoiceID = `inv_${string}`;\nexport type PhaseID = `phs_${string}`;\nexport type ItemID = `itm_${string}`;\nexport type ProductID = `prd_${string}`;\nexport type EventID = `evt_${string}`;\nexport type WebhookID = `wh_${string}`;\n\n// Currency enum\nexport type Currency =\n | \"USD\"\n | \"EUR\"\n | \"GBP\"\n | \"CAD\"\n | \"AUD\"\n | \"JPY\"\n | \"ARS\"\n | \"BRL\"\n | \"MXN\"\n | \"CLP\";\n\n// Common parameters\nexport interface ListParams extends Record<string, unknown> {\n limit?: number;\n cursor?: string;\n startDate?: string;\n endDate?: string;\n}\n\nexport interface RetrieveOptions {\n expand?: string[];\n}\n\n// Request options\nexport interface RequestOptions {\n idempotencyKey?: string;\n timeout?: number;\n}\n\n/**\n * Generated types interface - augmented by CLI after 'commet pull'\n *\n * This interface gets filled by module augmentation when you run `commet pull`.\n * The CLI generates a .commet/types.d.ts file that augments this interface with your\n * organization's specific feature codes, seat types, and plan codes.\n *\n * @example\n * // After running `commet pull`, TypeScript will automatically know your types:\n * await commet.usage.track({\n * feature: 'api_calls', // Autocomplete works!\n * externalId: 'user_123'\n * });\n */\n\n// biome-ignore lint/suspicious/noEmptyInterface: augmented by CLI-generated .commet/types.d.ts\nexport interface CommetGeneratedTypes {}\n\nexport type GeneratedSeatType = CommetGeneratedTypes extends {\n seatType: infer T;\n}\n ? T\n : string;\n\nexport type GeneratedPlanCode = CommetGeneratedTypes extends {\n planCode: infer T;\n}\n ? T\n : string;\n\nexport type GeneratedFeatureCode = CommetGeneratedTypes extends {\n featureCode: infer T;\n}\n ? T\n : string;\n","import type {\n ApiResponse,\n CommetConfig,\n Environment,\n RequestOptions,\n} from \"../types/common\";\nimport { CommetAPIError, CommetValidationError } from \"../types/common\";\n\nexport interface RetryConfig {\n maxRetries: number;\n baseDelay: number;\n maxDelay: number;\n retryableStatusCodes: number[];\n}\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 1000, // 1s\n maxDelay: 8000, // 8s\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\nexport class CommetHTTPClient {\n private config: CommetConfig;\n private environment: Environment;\n private retryConfig: RetryConfig;\n\n constructor(config: CommetConfig, environment: Environment) {\n this.config = config;\n this.environment = environment;\n this.retryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n maxRetries: config.retries ?? DEFAULT_RETRY_CONFIG.maxRetries,\n };\n }\n\n async get<T = unknown>(\n endpoint: string,\n params?: Record<string, unknown>,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"GET\", endpoint, undefined, options, params);\n }\n\n async post<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"POST\", endpoint, data, options);\n }\n\n async put<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"PUT\", endpoint, data, options);\n }\n\n async delete<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"DELETE\", endpoint, data, options);\n }\n\n /**\n * Core request method with retry logic\n */\n private async request<T = unknown>(\n method: string,\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n params?: Record<string, unknown>,\n ): Promise<ApiResponse<T>> {\n const url = this.buildURL(endpoint, params);\n return this.executeRequest(method, url, data, options);\n }\n\n /**\n * Execute real API request with retry logic\n */\n private async executeRequest<T = unknown>(\n method: string,\n url: string,\n data?: unknown,\n options?: RequestOptions,\n attempt = 1,\n ): Promise<ApiResponse<T>> {\n try {\n const headers: Record<string, string> = {\n \"x-api-key\": this.config.apiKey,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"commet/0.1.0\",\n };\n\n if (options?.idempotencyKey) {\n headers[\"Idempotency-Key\"] = options.idempotencyKey;\n } else if (method === \"POST\" && data) {\n headers[\"Idempotency-Key\"] = this.generateIdempotencyKey();\n }\n\n const requestConfig: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(\n options?.timeout ?? this.config.timeout ?? 30000,\n ),\n };\n\n if (data) {\n requestConfig.body = JSON.stringify(data);\n }\n\n if (this.config.debug) {\n console.log(`[Commet SDK] ${method} ${url}`);\n if (data) {\n console.log(\"Request data:\", JSON.stringify(data, null, 2));\n }\n }\n\n const response = await fetch(url, requestConfig);\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Response status: ${response.status} ${response.statusText}`,\n );\n }\n\n let responseData: unknown;\n let responseText: string;\n\n try {\n responseData = await response.json();\n responseText = \"\";\n } catch (jsonError) {\n try {\n responseText = await response.text();\n } catch (textError) {\n responseText = \"Failed to read response body\";\n }\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Failed to parse JSON response:\",\n responseText,\n );\n }\n\n // For 404 errors with invalid JSON, return a graceful response\n // This handles cases like HTML error pages or empty responses\n if (response.status === 404) {\n return {\n success: false,\n code: \"not_found\",\n message: \"Resource not found\",\n } as ApiResponse<T>;\n }\n\n throw new CommetAPIError(\n `Invalid JSON response: ${response.status} ${response.statusText}`,\n response.status,\n \"INVALID_JSON\",\n { responseText },\n );\n }\n\n if (!response.ok) {\n // Check if we should retry\n if (\n attempt <= this.retryConfig.maxRetries &&\n this.retryConfig.retryableStatusCodes.includes(response.status)\n ) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Retrying in ${delay}ms (attempt ${attempt}/${this.retryConfig.maxRetries})`,\n );\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n\n // Log error response for debugging\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Error response:\",\n JSON.stringify(responseData, null, 2),\n );\n }\n\n // Type guard for error response\n const isErrorResponse = (\n data: unknown,\n ): data is {\n message?: string;\n code?: string;\n details?: unknown;\n } => {\n return typeof data === \"object\" && data !== null;\n };\n\n const errorData = isErrorResponse(responseData) ? responseData : {};\n\n // Handle validation errors (new normalized shape)\n if (\n errorData.code === \"validation_error\" &&\n Array.isArray(errorData.details)\n ) {\n const errors: Record<string, string[]> = {};\n for (const detail of errorData.details as Array<{\n field: string;\n message: string;\n }>) {\n if (!errors[detail.field]) errors[detail.field] = [];\n errors[detail.field].push(detail.message);\n }\n throw new CommetValidationError(\n errorData.message || \"Validation failed\",\n errors,\n );\n }\n\n throw new CommetAPIError(\n errorData.message || `Request failed with status ${response.status}`,\n response.status,\n errorData.code,\n errorData.details,\n );\n }\n\n if (this.config.debug) {\n console.log(\"[Commet SDK] Response:\", responseData);\n }\n\n return responseData as ApiResponse<T>;\n } catch (error) {\n // Handle network errors and timeouts\n if (error instanceof TypeError && error.message.includes(\"fetch\")) {\n if (attempt <= this.retryConfig.maxRetries) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(`[Commet SDK] Network error, retrying in ${delay}ms`);\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Get base URL based on environment\n */\n private getBaseURL(): string {\n return this.environment === \"production\"\n ? \"https://commet.co\"\n : \"https://sandbox.commet.co\";\n }\n\n /**\n * Build full URL from endpoint and params\n */\n private buildURL(endpoint: string, params?: Record<string, unknown>): string {\n const baseURL = this.getBaseURL();\n\n // Construct full path with /api prefix\n const normalizedEndpoint = endpoint.startsWith(\"/\")\n ? endpoint\n : `/${endpoint}`;\n const fullPath = `/api${normalizedEndpoint}`;\n\n // Debug logging\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Building URL - baseURL: ${baseURL}, endpoint: ${endpoint}, fullPath: ${fullPath}`,\n );\n }\n\n const url = new URL(fullPath, baseURL);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n }\n }\n\n const finalUrl = url.toString();\n\n // Debug final URL\n if (this.config.debug) {\n console.log(`[Commet SDK] Final URL: ${finalUrl}`);\n }\n\n return finalUrl;\n }\n\n /**\n * Generate idempotency key\n */\n private generateIdempotencyKey(): string {\n // Generate UUID-like key for idempotency\n return `sdk_${Date.now()}_${Math.random().toString(36).substring(2)}`;\n }\n\n /**\n * Sleep for specified milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { CustomerContext } from \"./customer\";\nimport { CreditPacksResource } from \"./resources/credit-packs\";\nimport { CustomersResource } from \"./resources/customers\";\nimport { FeaturesResource } from \"./resources/features\";\nimport { PlansResource } from \"./resources/plans\";\nimport { PortalResource } from \"./resources/portal\";\nimport { SeatsResource } from \"./resources/seats\";\nimport { SubscriptionsResource } from \"./resources/subscriptions\";\nimport { UsageResource } from \"./resources/usage\";\nimport { Webhooks } from \"./resources/webhooks\";\nimport type { CommetConfig, Environment } from \"./types/common\";\nimport { CommetHTTPClient } from \"./utils/http\";\n\n/**\n * Main Commet SDK client\n */\nexport class Commet {\n private httpClient: CommetHTTPClient;\n private environment: Environment;\n\n public readonly customers: CustomersResource;\n public readonly creditPacks: CreditPacksResource;\n public readonly plans: PlansResource;\n public readonly usage: UsageResource;\n public readonly seats: SeatsResource;\n public readonly subscriptions: SubscriptionsResource;\n public readonly portal: PortalResource;\n public readonly features: FeaturesResource;\n public readonly webhooks: Webhooks;\n\n constructor(config: CommetConfig) {\n if (!config.apiKey) {\n throw new Error(\"Commet SDK: API key is required\");\n }\n\n if (!config.apiKey.startsWith(\"ck_\")) {\n throw new Error(\n \"Commet SDK: Invalid API key format. Expected format: ck_xxx...\",\n );\n }\n\n // Default to sandbox for safety\n this.environment = config.environment || \"sandbox\";\n\n this.httpClient = new CommetHTTPClient(config, this.environment);\n this.customers = new CustomersResource(this.httpClient);\n this.creditPacks = new CreditPacksResource(this.httpClient);\n this.plans = new PlansResource(this.httpClient);\n this.usage = new UsageResource(this.httpClient);\n this.seats = new SeatsResource(this.httpClient);\n this.subscriptions = new SubscriptionsResource(this.httpClient);\n this.portal = new PortalResource(this.httpClient);\n this.features = new FeaturesResource(this.httpClient);\n this.webhooks = new Webhooks();\n\n if (config.debug) {\n console.log(`[Commet SDK] Initialized in ${this.environment} mode`);\n console.log(\"API Key:\", `${config.apiKey.substring(0, 12)}...`);\n const baseURL =\n this.environment === \"production\"\n ? \"https://commet.co\"\n : \"https://sandbox.commet.co\";\n console.log(\"Base URL:\", baseURL);\n }\n }\n\n /**\n * Create a customer-scoped context for cleaner API usage\n *\n * @example\n * ```typescript\n * const customer = commet.customer(\"user_123\");\n *\n * // All operations are now scoped to this customer\n * const seats = await customer.features.get(\"team_members\");\n * await customer.seats.add(\"member\");\n * await customer.usage.track(\"api_call\");\n * ```\n */\n customer(externalId: string): CustomerContext {\n return new CustomerContext(externalId, {\n features: this.features,\n seats: this.seats,\n usage: this.usage,\n subscriptions: this.subscriptions,\n portal: this.portal,\n });\n }\n\n getEnvironment(): Environment {\n return this.environment;\n }\n\n isSandbox(): boolean {\n return this.environment === \"sandbox\";\n }\n\n isProduction(): boolean {\n return this.environment === \"production\";\n }\n}\n","import type { Environment } from \"../types/common\";\n\n/**\n * Check if environment is sandbox\n */\nexport function isSandbox(environment: Environment): boolean {\n return environment === \"sandbox\";\n}\n\n/**\n * Check if environment is production\n */\nexport function isProduction(environment: Environment): boolean {\n return environment === \"production\";\n}\n","/**\n * Commet SDK - Billing and usage tracking for SaaS\n */\nexport { Commet } from \"./client\";\nexport { CustomerContext } from \"./customer\";\n\n// Type exports\nexport type {\n CommetConfig,\n CommetGeneratedTypes,\n GeneratedSeatType,\n GeneratedPlanCode,\n GeneratedFeatureCode,\n Environment,\n ApiResponse,\n PaginatedResponse,\n PaginatedList,\n Currency,\n CustomerID,\n EventID,\n RequestOptions,\n} from \"./types/common\";\n\n// Error exports\nexport {\n CommetError,\n CommetAPIError,\n CommetValidationError,\n} from \"./types/common\";\n\n// Customers\nexport type {\n Customer,\n CustomerAddress,\n CreateParams as CreateCustomerParams,\n UpdateParams as UpdateCustomerParams,\n ListCustomersParams,\n BatchResult as CustomersBatchResult,\n} from \"./resources/customers\";\n\n// Usage\nexport type {\n UsageEvent,\n UsageEventProperty,\n TrackParams,\n TrackUsageParams,\n TrackModelTokensParams,\n BatchResult as UsageBatchResult,\n} from \"./resources/usage\";\n\n// Seats\nexport type {\n SeatEvent,\n SeatBalance,\n AddParams as AddSeatsParams,\n RemoveParams as RemoveSeatsParams,\n SetParams as SetSeatsParams,\n SetAllParams as SetAllSeatsParams,\n GetBalanceParams,\n GetAllBalancesParams,\n} from \"./resources/seats\";\n\n// Credit Packs\nexport type { CreditPack } from \"./resources/credit-packs\";\n\n// Plans\nexport type {\n Plan,\n PlanDetail,\n PlanPrice,\n PlanFeature,\n PlanID,\n BillingInterval,\n FeatureType,\n ListPlansParams,\n} from \"./resources/plans\";\n\n// Subscriptions\nexport type {\n CreatedSubscription,\n Subscription,\n ActiveSubscription,\n SubscriptionStatus,\n FeatureSummary,\n CreateSubscriptionParams,\n CancelParams,\n} from \"./resources/subscriptions\";\n\n// Portal\nexport type { PortalAccess, GetUrlParams } from \"./resources/portal\";\n\n// Features\nexport type {\n FeatureAccess,\n CanUseResult,\n CheckResult,\n GetFeatureParams,\n CheckFeatureParams,\n CanUseFeatureParams,\n} from \"./resources/features\";\n\n// Webhooks\nexport { Webhooks } from \"./resources/webhooks\";\nexport type {\n WebhookPayload,\n WebhookData,\n WebhookEvent,\n} from \"./resources/webhooks\";\n\n// Utility exports\nexport { isSandbox, isProduction } from \"./utils/environment\";\n\n// Default export\nimport { Commet } from \"./client\";\nexport default Commet;\n"],"mappings":"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","names":["data"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commet/node",
3
- "version": "1.6.2",
3
+ "version": "1.7.0",
4
4
  "description": "Commet SDK for Node.js - Billing and usage tracking",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",