@commet/node 1.6.0 → 1.6.2

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/dist/index.d.mts CHANGED
@@ -9,8 +9,9 @@ type CommetConfig = {
9
9
  interface ApiResponse<T = unknown> {
10
10
  success: boolean;
11
11
  data?: T;
12
- error?: string;
12
+ code?: string;
13
13
  message?: string;
14
+ details?: unknown;
14
15
  hasMore?: boolean;
15
16
  nextCursor?: string;
16
17
  }
@@ -57,39 +58,24 @@ interface RequestOptions {
57
58
  * Generated types interface - augmented by CLI after 'commet pull'
58
59
  *
59
60
  * This interface gets filled by module augmentation when you run `commet pull`.
60
- * The CLI generates a .commet.d.ts file that augments this interface with your
61
- * organization's specific event and seat types.
61
+ * The CLI generates a .commet/types.d.ts file that augments this interface with your
62
+ * organization's specific feature codes, seat types, and plan codes.
62
63
  *
63
64
  * @example
64
65
  * // After running `commet pull`, TypeScript will automatically know your types:
65
- * await commet.usage.events.create({
66
- * eventType: 'api_call', // Autocomplete works!
67
- * customerId: 'cus_123'
66
+ * await commet.usage.track({
67
+ * feature: 'api_calls', // Autocomplete works!
68
+ * externalId: 'user_123'
68
69
  * });
69
70
  */
70
71
  interface CommetGeneratedTypes {
71
72
  }
72
- /**
73
- * Helper type that provides fallback to string if types are not generated
74
- */
75
- type GeneratedEventType = CommetGeneratedTypes extends {
76
- eventType: infer T;
77
- } ? T : string;
78
- /**
79
- * Helper type that provides fallback to string if types are not generated
80
- */
81
73
  type GeneratedSeatType = CommetGeneratedTypes extends {
82
74
  seatType: infer T;
83
75
  } ? T : string;
84
- /**
85
- * Helper type that provides fallback to string if types are not generated
86
- */
87
76
  type GeneratedPlanCode = CommetGeneratedTypes extends {
88
77
  planCode: infer T;
89
78
  } ? T : string;
90
- /**
91
- * Helper type that provides fallback to string if types are not generated
92
- */
93
79
  type GeneratedFeatureCode = CommetGeneratedTypes extends {
94
80
  featureCode: infer T;
95
81
  } ? T : string;
@@ -408,6 +394,7 @@ interface PlanFeature {
408
394
  code: string;
409
395
  name: string;
410
396
  type: FeatureType;
397
+ unitName: string | null;
411
398
  enabled?: boolean;
412
399
  includedAmount?: number;
413
400
  unlimited?: boolean;
@@ -440,7 +427,6 @@ interface PlanDetailPrice {
440
427
  } | null;
441
428
  }
442
429
  interface PlanDetailFeature extends PlanFeature {
443
- unitName: string | null;
444
430
  overage: {
445
431
  enabled: boolean;
446
432
  model: "per_unit" | "tiered" | null;
@@ -674,7 +660,7 @@ interface BatchResult$1<T> {
674
660
  }>;
675
661
  }
676
662
  interface TrackParams {
677
- feature: string;
663
+ feature: GeneratedFeatureCode;
678
664
  customerId?: CustomerID;
679
665
  externalId?: string;
680
666
  idempotencyKey?: string;
@@ -789,6 +775,32 @@ declare class CustomerContext {
789
775
  };
790
776
  }
791
777
 
778
+ interface CreditPack {
779
+ id: string;
780
+ name: string;
781
+ description: string | null;
782
+ credits: number;
783
+ price: number;
784
+ currency: string;
785
+ }
786
+ /**
787
+ * Credit Packs resource for listing available credit packs
788
+ */
789
+ declare class CreditPacksResource {
790
+ private httpClient;
791
+ constructor(httpClient: CommetHTTPClient);
792
+ /**
793
+ * List all active credit packs
794
+ *
795
+ * @example
796
+ * ```typescript
797
+ * const packs = await commet.creditPacks.list();
798
+ * console.log(packs.data); // [{ id: "cp_xxx", name: "100 Credits", ... }]
799
+ * ```
800
+ */
801
+ list(): Promise<ApiResponse<CreditPack[]>>;
802
+ }
803
+
792
804
  interface Customer {
793
805
  id: CustomerID;
794
806
  organizationId: string;
@@ -885,32 +897,6 @@ declare class CustomersResource {
885
897
  archive(customerId: CustomerID, options?: RequestOptions): Promise<ApiResponse<Customer>>;
886
898
  }
887
899
 
888
- interface CreditPack {
889
- id: string;
890
- name: string;
891
- description: string | null;
892
- credits: number;
893
- price: number;
894
- currency: string;
895
- }
896
- /**
897
- * Credit Packs resource for listing available credit packs
898
- */
899
- declare class CreditPacksResource {
900
- private httpClient;
901
- constructor(httpClient: CommetHTTPClient);
902
- /**
903
- * List all active credit packs
904
- *
905
- * @example
906
- * ```typescript
907
- * const packs = await commet.creditPacks.list();
908
- * console.log(packs.data); // [{ id: "cp_xxx", name: "100 Credits", ... }]
909
- * ```
910
- */
911
- list(): Promise<ApiResponse<CreditPack[]>>;
912
- }
913
-
914
900
  /**
915
901
  * Webhook payload structure from Commet
916
902
  */
@@ -1063,4 +1049,4 @@ declare function isProduction(environment: Environment): boolean;
1063
1049
  * Commet SDK - Billing and usage tracking for SaaS
1064
1050
  */
1065
1051
 
1066
- 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 GeneratedEventType, 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 };
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 };
package/dist/index.d.ts CHANGED
@@ -9,8 +9,9 @@ type CommetConfig = {
9
9
  interface ApiResponse<T = unknown> {
10
10
  success: boolean;
11
11
  data?: T;
12
- error?: string;
12
+ code?: string;
13
13
  message?: string;
14
+ details?: unknown;
14
15
  hasMore?: boolean;
15
16
  nextCursor?: string;
16
17
  }
@@ -57,39 +58,24 @@ interface RequestOptions {
57
58
  * Generated types interface - augmented by CLI after 'commet pull'
58
59
  *
59
60
  * This interface gets filled by module augmentation when you run `commet pull`.
60
- * The CLI generates a .commet.d.ts file that augments this interface with your
61
- * organization's specific event and seat types.
61
+ * The CLI generates a .commet/types.d.ts file that augments this interface with your
62
+ * organization's specific feature codes, seat types, and plan codes.
62
63
  *
63
64
  * @example
64
65
  * // After running `commet pull`, TypeScript will automatically know your types:
65
- * await commet.usage.events.create({
66
- * eventType: 'api_call', // Autocomplete works!
67
- * customerId: 'cus_123'
66
+ * await commet.usage.track({
67
+ * feature: 'api_calls', // Autocomplete works!
68
+ * externalId: 'user_123'
68
69
  * });
69
70
  */
70
71
  interface CommetGeneratedTypes {
71
72
  }
72
- /**
73
- * Helper type that provides fallback to string if types are not generated
74
- */
75
- type GeneratedEventType = CommetGeneratedTypes extends {
76
- eventType: infer T;
77
- } ? T : string;
78
- /**
79
- * Helper type that provides fallback to string if types are not generated
80
- */
81
73
  type GeneratedSeatType = CommetGeneratedTypes extends {
82
74
  seatType: infer T;
83
75
  } ? T : string;
84
- /**
85
- * Helper type that provides fallback to string if types are not generated
86
- */
87
76
  type GeneratedPlanCode = CommetGeneratedTypes extends {
88
77
  planCode: infer T;
89
78
  } ? T : string;
90
- /**
91
- * Helper type that provides fallback to string if types are not generated
92
- */
93
79
  type GeneratedFeatureCode = CommetGeneratedTypes extends {
94
80
  featureCode: infer T;
95
81
  } ? T : string;
@@ -408,6 +394,7 @@ interface PlanFeature {
408
394
  code: string;
409
395
  name: string;
410
396
  type: FeatureType;
397
+ unitName: string | null;
411
398
  enabled?: boolean;
412
399
  includedAmount?: number;
413
400
  unlimited?: boolean;
@@ -440,7 +427,6 @@ interface PlanDetailPrice {
440
427
  } | null;
441
428
  }
442
429
  interface PlanDetailFeature extends PlanFeature {
443
- unitName: string | null;
444
430
  overage: {
445
431
  enabled: boolean;
446
432
  model: "per_unit" | "tiered" | null;
@@ -674,7 +660,7 @@ interface BatchResult$1<T> {
674
660
  }>;
675
661
  }
676
662
  interface TrackParams {
677
- feature: string;
663
+ feature: GeneratedFeatureCode;
678
664
  customerId?: CustomerID;
679
665
  externalId?: string;
680
666
  idempotencyKey?: string;
@@ -789,6 +775,32 @@ declare class CustomerContext {
789
775
  };
790
776
  }
791
777
 
778
+ interface CreditPack {
779
+ id: string;
780
+ name: string;
781
+ description: string | null;
782
+ credits: number;
783
+ price: number;
784
+ currency: string;
785
+ }
786
+ /**
787
+ * Credit Packs resource for listing available credit packs
788
+ */
789
+ declare class CreditPacksResource {
790
+ private httpClient;
791
+ constructor(httpClient: CommetHTTPClient);
792
+ /**
793
+ * List all active credit packs
794
+ *
795
+ * @example
796
+ * ```typescript
797
+ * const packs = await commet.creditPacks.list();
798
+ * console.log(packs.data); // [{ id: "cp_xxx", name: "100 Credits", ... }]
799
+ * ```
800
+ */
801
+ list(): Promise<ApiResponse<CreditPack[]>>;
802
+ }
803
+
792
804
  interface Customer {
793
805
  id: CustomerID;
794
806
  organizationId: string;
@@ -885,32 +897,6 @@ declare class CustomersResource {
885
897
  archive(customerId: CustomerID, options?: RequestOptions): Promise<ApiResponse<Customer>>;
886
898
  }
887
899
 
888
- interface CreditPack {
889
- id: string;
890
- name: string;
891
- description: string | null;
892
- credits: number;
893
- price: number;
894
- currency: string;
895
- }
896
- /**
897
- * Credit Packs resource for listing available credit packs
898
- */
899
- declare class CreditPacksResource {
900
- private httpClient;
901
- constructor(httpClient: CommetHTTPClient);
902
- /**
903
- * List all active credit packs
904
- *
905
- * @example
906
- * ```typescript
907
- * const packs = await commet.creditPacks.list();
908
- * console.log(packs.data); // [{ id: "cp_xxx", name: "100 Credits", ... }]
909
- * ```
910
- */
911
- list(): Promise<ApiResponse<CreditPack[]>>;
912
- }
913
-
914
900
  /**
915
901
  * Webhook payload structure from Commet
916
902
  */
@@ -1063,4 +1049,4 @@ declare function isProduction(environment: Environment): boolean;
1063
1049
  * Commet SDK - Billing and usage tracking for SaaS
1064
1050
  */
1065
1051
 
1066
- 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 GeneratedEventType, 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 };
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 };
package/dist/index.js CHANGED
@@ -108,6 +108,25 @@ var CustomerContext = class {
108
108
  }
109
109
  };
110
110
 
111
+ // src/resources/credit-packs.ts
112
+ var CreditPacksResource = class {
113
+ constructor(httpClient) {
114
+ this.httpClient = httpClient;
115
+ }
116
+ /**
117
+ * List all active credit packs
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * const packs = await commet.creditPacks.list();
122
+ * console.log(packs.data); // [{ id: "cp_xxx", name: "100 Credits", ... }]
123
+ * ```
124
+ */
125
+ async list() {
126
+ return this.httpClient.get("/credit-packs");
127
+ }
128
+ };
129
+
111
130
  // src/resources/customers.ts
112
131
  var CustomersResource = class {
113
132
  constructor(httpClient) {
@@ -296,25 +315,6 @@ var FeaturesResource = class {
296
315
  }
297
316
  };
298
317
 
299
- // src/resources/credit-packs.ts
300
- var CreditPacksResource = class {
301
- constructor(httpClient) {
302
- this.httpClient = httpClient;
303
- }
304
- /**
305
- * List all active credit packs
306
- *
307
- * @example
308
- * ```typescript
309
- * const packs = await commet.creditPacks.list();
310
- * console.log(packs.data); // [{ id: "cp_xxx", name: "100 Credits", ... }]
311
- * ```
312
- */
313
- async list() {
314
- return this.httpClient.get("/credit-packs");
315
- }
316
- };
317
-
318
318
  // src/resources/plans.ts
319
319
  var PlansResource = class {
320
320
  constructor(httpClient) {
@@ -800,7 +800,8 @@ var CommetHTTPClient = class {
800
800
  if (response.status === 404) {
801
801
  return {
802
802
  success: false,
803
- error: "Resource not found"
803
+ code: "not_found",
804
+ message: "Resource not found"
804
805
  };
805
806
  }
806
807
  throw new CommetAPIError(
@@ -834,10 +835,15 @@ var CommetHTTPClient = class {
834
835
  return typeof data2 === "object" && data2 !== null;
835
836
  };
836
837
  const errorData = isErrorResponse(responseData) ? responseData : {};
837
- if (response.status === 400 && errorData.errors) {
838
+ if (errorData.code === "validation_error" && Array.isArray(errorData.details)) {
839
+ const errors = {};
840
+ for (const detail of errorData.details) {
841
+ if (!errors[detail.field]) errors[detail.field] = [];
842
+ errors[detail.field].push(detail.message);
843
+ }
838
844
  throw new CommetValidationError(
839
845
  errorData.message || "Validation failed",
840
- errorData.errors
846
+ errors
841
847
  );
842
848
  }
843
849
  throw new CommetAPIError(
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/customer.ts","../src/resources/customers.ts","../src/resources/features.ts","../src/resources/credit-packs.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 GeneratedEventType,\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 {\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 { 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 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 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 unitName: string | null;\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 GeneratedEventType,\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: string;\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 error?: string;\n message?: string;\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.d.ts file that augments this interface with your\n * organization's specific event and seat types.\n *\n * @example\n * // After running `commet pull`, TypeScript will automatically know your types:\n * await commet.usage.events.create({\n * eventType: 'api_call', // Autocomplete works!\n * customerId: 'cus_123'\n * });\n */\n\n// biome-ignore lint/suspicious/noEmptyInterface: <explanation>\nexport interface CommetGeneratedTypes {}\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedEventType = CommetGeneratedTypes extends {\n eventType: infer T;\n}\n ? T\n : string;\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedSeatType = CommetGeneratedTypes extends {\n seatType: infer T;\n}\n ? T\n : string;\n\n/**\n * Helper type that provides fallback to string if types are not generated\n * @deprecated Use GeneratedPlanCode instead\n */\nexport type GeneratedProductId = CommetGeneratedTypes extends {\n productId: infer T;\n}\n ? T\n : string;\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedPlanCode = CommetGeneratedTypes extends {\n planCode: infer T;\n}\n ? T\n : string;\n\n/**\n * Helper type that provides fallback to string if types are not generated\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 error: \"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 errors?: Record<string, 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 different error types\n if (response.status === 400 && errorData.errors) {\n throw new CommetValidationError(\n errorData.message || \"Validation failed\",\n errorData.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 { CustomersResource } from \"./resources/customers\";\nimport { FeaturesResource } from \"./resources/features\";\nimport { CreditPacksResource } from \"./resources/credit-packs\";\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 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"]}
package/dist/index.mjs CHANGED
@@ -64,6 +64,25 @@ var CustomerContext = class {
64
64
  }
65
65
  };
66
66
 
67
+ // src/resources/credit-packs.ts
68
+ var CreditPacksResource = class {
69
+ constructor(httpClient) {
70
+ this.httpClient = httpClient;
71
+ }
72
+ /**
73
+ * List all active credit packs
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * const packs = await commet.creditPacks.list();
78
+ * console.log(packs.data); // [{ id: "cp_xxx", name: "100 Credits", ... }]
79
+ * ```
80
+ */
81
+ async list() {
82
+ return this.httpClient.get("/credit-packs");
83
+ }
84
+ };
85
+
67
86
  // src/resources/customers.ts
68
87
  var CustomersResource = class {
69
88
  constructor(httpClient) {
@@ -252,25 +271,6 @@ var FeaturesResource = class {
252
271
  }
253
272
  };
254
273
 
255
- // src/resources/credit-packs.ts
256
- var CreditPacksResource = class {
257
- constructor(httpClient) {
258
- this.httpClient = httpClient;
259
- }
260
- /**
261
- * List all active credit packs
262
- *
263
- * @example
264
- * ```typescript
265
- * const packs = await commet.creditPacks.list();
266
- * console.log(packs.data); // [{ id: "cp_xxx", name: "100 Credits", ... }]
267
- * ```
268
- */
269
- async list() {
270
- return this.httpClient.get("/credit-packs");
271
- }
272
- };
273
-
274
274
  // src/resources/plans.ts
275
275
  var PlansResource = class {
276
276
  constructor(httpClient) {
@@ -756,7 +756,8 @@ var CommetHTTPClient = class {
756
756
  if (response.status === 404) {
757
757
  return {
758
758
  success: false,
759
- error: "Resource not found"
759
+ code: "not_found",
760
+ message: "Resource not found"
760
761
  };
761
762
  }
762
763
  throw new CommetAPIError(
@@ -790,10 +791,15 @@ var CommetHTTPClient = class {
790
791
  return typeof data2 === "object" && data2 !== null;
791
792
  };
792
793
  const errorData = isErrorResponse(responseData) ? responseData : {};
793
- if (response.status === 400 && errorData.errors) {
794
+ if (errorData.code === "validation_error" && Array.isArray(errorData.details)) {
795
+ const errors = {};
796
+ for (const detail of errorData.details) {
797
+ if (!errors[detail.field]) errors[detail.field] = [];
798
+ errors[detail.field].push(detail.message);
799
+ }
794
800
  throw new CommetValidationError(
795
801
  errorData.message || "Validation failed",
796
- errorData.errors
802
+ errors
797
803
  );
798
804
  }
799
805
  throw new CommetAPIError(
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/customer.ts","../src/resources/customers.ts","../src/resources/features.ts","../src/resources/credit-packs.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 {\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 { 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 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 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 unitName: string | null;\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 GeneratedEventType,\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: string;\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 error?: string;\n message?: string;\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.d.ts file that augments this interface with your\n * organization's specific event and seat types.\n *\n * @example\n * // After running `commet pull`, TypeScript will automatically know your types:\n * await commet.usage.events.create({\n * eventType: 'api_call', // Autocomplete works!\n * customerId: 'cus_123'\n * });\n */\n\n// biome-ignore lint/suspicious/noEmptyInterface: <explanation>\nexport interface CommetGeneratedTypes {}\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedEventType = CommetGeneratedTypes extends {\n eventType: infer T;\n}\n ? T\n : string;\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedSeatType = CommetGeneratedTypes extends {\n seatType: infer T;\n}\n ? T\n : string;\n\n/**\n * Helper type that provides fallback to string if types are not generated\n * @deprecated Use GeneratedPlanCode instead\n */\nexport type GeneratedProductId = CommetGeneratedTypes extends {\n productId: infer T;\n}\n ? T\n : string;\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedPlanCode = CommetGeneratedTypes extends {\n planCode: infer T;\n}\n ? T\n : string;\n\n/**\n * Helper type that provides fallback to string if types are not generated\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 error: \"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 errors?: Record<string, 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 different error types\n if (response.status === 400 && errorData.errors) {\n throw new CommetValidationError(\n errorData.message || \"Validation failed\",\n errorData.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 { CustomersResource } from \"./resources/customers\";\nimport { FeaturesResource } from \"./resources/features\";\nimport { CreditPacksResource } from \"./resources/credit-packs\";\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 GeneratedEventType,\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\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commet/node",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
4
4
  "description": "Commet SDK for Node.js - Billing and usage tracking",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",