chargebee 3.31.0 → 3.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ### v3.32.0 (2026-09-08)
2
+ * * *
3
+ ### New Features
4
+ * Added anonymous SDK telemetry. On the first API call of a client instance, the SDK may attach an `x-chargebee-sdk-telemetry` header listing enabled feature codes (`telemetryAdapter`, custom HTTP client, retry config). Later calls on the same client do not send the header again. A default client with no optional features sends no telemetry header.
5
+ * Disable SDK telemetry with `sdkTelemetryEnabled: false`.
6
+ * Exported `SDK_TELEMETRY_HEADER_NAME` from the CJS and ESM entry points.
7
+
8
+
1
9
  ### v3.31.0 (2026-08-19)
2
10
  * * *
3
11
  ### New Resources:
package/README.md CHANGED
@@ -602,6 +602,20 @@ const chargebee = new Chargebee({
602
602
 
603
603
  These examples demonstrate how to implement and inject custom clients using `axios` and `ky`, respectively.
604
604
 
605
+ ### SDK telemetry
606
+
607
+ By default, the library sends anonymous usage telemetry to Chargebee. This helps us improve the SDK and API.
608
+
609
+ You can disable this behavior if you prefer:
610
+
611
+ ```javascript
612
+ const chargebee = new Chargebee({
613
+ site: 'your-site',
614
+ apiKey: 'your-api-key',
615
+ sdkTelemetryEnabled: false,
616
+ });
617
+ ```
618
+
605
619
  ### Telemetry (OpenTelemetry)
606
620
 
607
621
  Optional. Pass a `telemetryAdapter` when you want Chargebee API calls traced in your observability stack (Datadog, Splunk, Honeycomb, Jaeger, etc.). The SDK ships a ready-to-use OpenTelemetry adapter, so for most setups you only need to add `@opentelemetry/api` and wire the adapter on the client.
@@ -68,6 +68,15 @@ class RequestWrapper {
68
68
  if (this.envArg.telemetryAdapter !== undefined) {
69
69
  _env.telemetryAdapter = this.envArg.telemetryAdapter;
70
70
  }
71
+ if (this.envArg.sdkTelemetryState !== undefined) {
72
+ _env.sdkTelemetryState = this.envArg.sdkTelemetryState;
73
+ }
74
+ if (this.envArg.sdkTelemetryEnabled !== undefined) {
75
+ _env.sdkTelemetryEnabled = this.envArg.sdkTelemetryEnabled;
76
+ }
77
+ if (this.envArg.httpClientIsCustom !== undefined) {
78
+ _env.httpClientIsCustom = this.envArg.httpClientIsCustom;
79
+ }
71
80
  const env = _env;
72
81
  const retryConfig = Object.assign({ enabled: false, maxRetries: 3, delayMs: 200, retryOn: [500, 502, 503, 504] }, env.retryConfig);
73
82
  const urlIdParam = this.apiCall.hasIdInUrl ? this.args[0] : null;
@@ -142,6 +151,7 @@ class RequestWrapper {
142
151
  : (0, util_js_1.encodeParams)(requestParams, undefined, undefined, undefined, jsonKeys);
143
152
  }
144
153
  const requestHeaders = Object.assign(Object.assign({}, this.httpHeaders), telemetryHeaders);
154
+ (0, index_js_1.attachSdkTelemetryHeader)(env, requestHeaders);
145
155
  const contentType = this.apiCall.isJsonRequest
146
156
  ? 'application/json;charset=UTF-8'
147
157
  : 'application/x-www-form-urlencoded; charset=utf-8';
@@ -264,9 +274,10 @@ class RequestWrapper {
264
274
  throw err;
265
275
  }
266
276
  };
267
- const promise = telemetryAdapter !== undefined
277
+ const executeCall = () => telemetryAdapter !== undefined
268
278
  ? runWithTelemetry(telemetryAdapter)
269
279
  : withRetry(0, requestStartTime);
280
+ const promise = executeCall();
270
281
  return (0, util_js_1.callbackifyPromise)(promise);
271
282
  }
272
283
  _createHeaders(httpHeaders) {
@@ -21,5 +21,6 @@ module.exports.WebhookAuthenticationError = handler_js_1.WebhookAuthenticationEr
21
21
  module.exports.WebhookPayloadValidationError = handler_js_1.WebhookPayloadValidationError;
22
22
  module.exports.WebhookPayloadParseError = handler_js_1.WebhookPayloadParseError;
23
23
  module.exports.TelemetryAttributeKeys = index_js_1.TelemetryAttributeKeys;
24
+ module.exports.SDK_TELEMETRY_HEADER_NAME = index_js_1.SDK_TELEMETRY_HEADER_NAME;
24
25
  // Export validation error class
25
26
  module.exports.ChargebeeZodValidationError = chargebeeZodValidationError_js_1.ChargebeeZodValidationError;
@@ -18,14 +18,18 @@ const api_endpoints_js_1 = require("./resources/api_endpoints.js");
18
18
  const util_js_1 = require("./util.js");
19
19
  const asyncApiSupport_js_1 = require("./asyncApiSupport.js");
20
20
  const handler_js_1 = require("./resources/webhook/handler.js");
21
+ const index_js_1 = require("./telemetry/index.js");
21
22
  const CreateChargebee = (httpClient) => {
22
23
  const Chargebee = function (conf) {
23
24
  this._env = Object.assign({}, environment_js_1.Environment);
24
- const { telemetryAdapter, httpClient: configHttpClient } = conf, confToMerge = __rest(conf, ["telemetryAdapter", "httpClient"]);
25
+ const { telemetryAdapter, httpClient: configHttpClient, sdkTelemetryEnabled } = conf, confToMerge = __rest(conf, ["telemetryAdapter", "httpClient", "sdkTelemetryEnabled"]);
25
26
  (0, util_js_1.extend)(true, this._env, confToMerge);
26
27
  // @ts-ignore
27
28
  this._env.httpClient =
28
29
  configHttpClient != null ? configHttpClient : httpClient;
30
+ this._env.sdkTelemetryState = new index_js_1.SdkTelemetryState();
31
+ this._env.sdkTelemetryEnabled = sdkTelemetryEnabled !== false;
32
+ this._env.httpClientIsCustom = configHttpClient != null;
29
33
  if (telemetryAdapter !== undefined) {
30
34
  this._env.telemetryAdapter = telemetryAdapter;
31
35
  }
@@ -11,7 +11,7 @@ exports.Environment = {
11
11
  hostSuffix: '.chargebee.com',
12
12
  apiPath: '/api/v2',
13
13
  timeout: DEFAULT_TIME_OUT,
14
- clientVersion: 'v3.31.0',
14
+ clientVersion: 'v3.32.0',
15
15
  port: DEFAULT_PORT,
16
16
  timemachineWaitInMillis: DEFAULT_TIME_MACHINE_WAIT,
17
17
  exportWaitInMillis: DEFAULT_EXPORT_WAIT,
@@ -6,7 +6,7 @@
6
6
  * Copyright 2026 Chargebee Inc.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.resolveChargebeeApiVersion = exports.extractRequestTelemetryError = exports.extractHttpStatusCode = exports.buildSpanName = exports.buildRequestTelemetryResult = exports.buildRequestTelemetryContext = exports.buildRequestStartSpanAttributes = exports.buildRequestHeaderSpanAttributes = exports.buildRequestEndSpanAttributes = exports.NoOpTelemetryAdapter = exports.NO_OP_TELEMETRY_ADAPTER = exports.TelemetryAttributeKeys = exports.TELEMETRY_SPAN_NAME_PREFIX = exports.HTTP_REQUEST_HEADER_ATTRIBUTE_PREFIX = exports.CHARGEBEE_TELEMETRY_HEADER_PREFIX = exports.CHARGEBEE_TELEMETRY_HEADER_EXCLUDE_PREFIX = exports.CHARGEBEE_SDK_NAME = void 0;
9
+ exports.attachSdkTelemetryHeader = exports.buildSdkTelemetryHeader = exports.SdkTelemetryState = exports.SdkTelemetryFeature = exports.SDK_TELEMETRY_MAX_HEADER_BYTES = exports.SDK_TELEMETRY_HEADER_NAME = exports.SDK_TELEMETRY_FEATURES_KEY = exports.resolveChargebeeApiVersion = exports.extractRequestTelemetryError = exports.extractHttpStatusCode = exports.buildSpanName = exports.buildRequestTelemetryResult = exports.buildRequestTelemetryContext = exports.buildRequestStartSpanAttributes = exports.buildRequestHeaderSpanAttributes = exports.buildRequestEndSpanAttributes = exports.NoOpTelemetryAdapter = exports.NO_OP_TELEMETRY_ADAPTER = exports.TelemetryAttributeKeys = exports.TELEMETRY_SPAN_NAME_PREFIX = exports.HTTP_REQUEST_HEADER_ATTRIBUTE_PREFIX = exports.CHARGEBEE_TELEMETRY_HEADER_PREFIX = exports.CHARGEBEE_TELEMETRY_HEADER_EXCLUDE_PREFIX = exports.CHARGEBEE_SDK_NAME = void 0;
10
10
  var types_js_1 = require("./types.js");
11
11
  Object.defineProperty(exports, "CHARGEBEE_SDK_NAME", { enumerable: true, get: function () { return types_js_1.CHARGEBEE_SDK_NAME; } });
12
12
  Object.defineProperty(exports, "CHARGEBEE_TELEMETRY_HEADER_EXCLUDE_PREFIX", { enumerable: true, get: function () { return types_js_1.CHARGEBEE_TELEMETRY_HEADER_EXCLUDE_PREFIX; } });
@@ -26,3 +26,15 @@ Object.defineProperty(exports, "buildSpanName", { enumerable: true, get: functio
26
26
  Object.defineProperty(exports, "extractHttpStatusCode", { enumerable: true, get: function () { return TelemetryAdapter_js_1.extractHttpStatusCode; } });
27
27
  Object.defineProperty(exports, "extractRequestTelemetryError", { enumerable: true, get: function () { return TelemetryAdapter_js_1.extractRequestTelemetryError; } });
28
28
  Object.defineProperty(exports, "resolveChargebeeApiVersion", { enumerable: true, get: function () { return TelemetryAdapter_js_1.resolveChargebeeApiVersion; } });
29
+ var sdkTelemetryHeader_js_1 = require("./sdkTelemetryHeader.js");
30
+ Object.defineProperty(exports, "SDK_TELEMETRY_FEATURES_KEY", { enumerable: true, get: function () { return sdkTelemetryHeader_js_1.SDK_TELEMETRY_FEATURES_KEY; } });
31
+ Object.defineProperty(exports, "SDK_TELEMETRY_HEADER_NAME", { enumerable: true, get: function () { return sdkTelemetryHeader_js_1.SDK_TELEMETRY_HEADER_NAME; } });
32
+ Object.defineProperty(exports, "SDK_TELEMETRY_MAX_HEADER_BYTES", { enumerable: true, get: function () { return sdkTelemetryHeader_js_1.SDK_TELEMETRY_MAX_HEADER_BYTES; } });
33
+ var sdkTelemetryFeature_js_1 = require("./sdkTelemetryFeature.js");
34
+ Object.defineProperty(exports, "SdkTelemetryFeature", { enumerable: true, get: function () { return sdkTelemetryFeature_js_1.SdkTelemetryFeature; } });
35
+ var sdkTelemetryState_js_1 = require("./sdkTelemetryState.js");
36
+ Object.defineProperty(exports, "SdkTelemetryState", { enumerable: true, get: function () { return sdkTelemetryState_js_1.SdkTelemetryState; } });
37
+ var sdkTelemetryHeaderBuilder_js_1 = require("./sdkTelemetryHeaderBuilder.js");
38
+ Object.defineProperty(exports, "buildSdkTelemetryHeader", { enumerable: true, get: function () { return sdkTelemetryHeaderBuilder_js_1.buildSdkTelemetryHeader; } });
39
+ var sdkTelemetryEmitter_js_1 = require("./sdkTelemetryEmitter.js");
40
+ Object.defineProperty(exports, "attachSdkTelemetryHeader", { enumerable: true, get: function () { return sdkTelemetryEmitter_js_1.attachSdkTelemetryHeader; } });
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ /*
3
+ * This file is auto-generated by Chargebee.
4
+ * For more information on how to make changes to this file, please see the README.
5
+ * Reach out to dx@chargebee.com for any questions.
6
+ * Copyright 2026 Chargebee Inc.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.attachSdkTelemetryHeader = attachSdkTelemetryHeader;
10
+ const sdkTelemetryHeaderBuilder_js_1 = require("./sdkTelemetryHeaderBuilder.js");
11
+ const sdkTelemetryFeature_js_1 = require("./sdkTelemetryFeature.js");
12
+ const sdkTelemetryHeader_js_1 = require("./sdkTelemetryHeader.js");
13
+ /**
14
+ * Emits the anonymous SDK telemetry request header, independently of any customer telemetry
15
+ * adapter.
16
+ *
17
+ * On the first API call of a client instance, attaches {@code f;…} with enabled feature codes when
18
+ * any are present; omits the header when none are enabled. Later calls on the same client never
19
+ * attach again. SDK identity is correlated via User-Agent. Every failure path is swallowed and
20
+ * logged at WARNING: telemetry must never fail an API call.
21
+ */
22
+ function attachSdkTelemetryHeader(env, headers) {
23
+ var _a;
24
+ if (env.sdkTelemetryEnabled === false) {
25
+ return;
26
+ }
27
+ try {
28
+ if (!((_a = env.sdkTelemetryState) === null || _a === void 0 ? void 0 : _a.tryMarkEmitted())) {
29
+ return;
30
+ }
31
+ const headerValue = (0, sdkTelemetryHeaderBuilder_js_1.buildSdkTelemetryHeader)(resolveFeatures(env));
32
+ if (!headerValue) {
33
+ return;
34
+ }
35
+ headers[sdkTelemetryHeader_js_1.SDK_TELEMETRY_HEADER_NAME] = headerValue;
36
+ }
37
+ catch (err) {
38
+ logSuppressed('attach header', err);
39
+ }
40
+ }
41
+ /** Collects enabled feature codes for the current client configuration. */
42
+ function resolveFeatures(env) {
43
+ const features = [];
44
+ if (env.telemetryAdapter !== undefined) {
45
+ features.push(sdkTelemetryFeature_js_1.SdkTelemetryFeature.TELEMETRY_ADAPTER);
46
+ }
47
+ if (env.httpClientIsCustom) {
48
+ features.push(sdkTelemetryFeature_js_1.SdkTelemetryFeature.CUSTOM_TRANSPORT);
49
+ }
50
+ if (isRetryConfigActive(env)) {
51
+ features.push(sdkTelemetryFeature_js_1.SdkTelemetryFeature.RETRY_CONFIG);
52
+ }
53
+ return features;
54
+ }
55
+ /** Whether retries are enabled on the client. */
56
+ function isRetryConfigActive(env) {
57
+ var _a;
58
+ return ((_a = env.retryConfig) === null || _a === void 0 ? void 0 : _a.enabled) === true;
59
+ }
60
+ /** Logs a suppressed telemetry failure without affecting the API call. */
61
+ function logSuppressed(step, err) {
62
+ const message = err instanceof Error ? err.message : String(err);
63
+ console.warn(`SDK telemetry could not ${step} (${message}); API call unaffected.`, err);
64
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /*
3
+ * This file is auto-generated by Chargebee.
4
+ * For more information on how to make changes to this file, please see the README.
5
+ * Reach out to dx@chargebee.com for any questions.
6
+ * Copyright 2026 Chargebee Inc.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.SdkTelemetryFeature = void 0;
10
+ /**
11
+ * SDK configuration features reported under the {@code f} segment of
12
+ * {@link SDK_TELEMETRY_HEADER_NAME}. Wire codes are maintained in sdk-generator.
13
+ */
14
+ var SdkTelemetryFeature;
15
+ (function (SdkTelemetryFeature) {
16
+ /** Customer TelemetryAdapter configured. */
17
+ SdkTelemetryFeature["TELEMETRY_ADAPTER"] = "ta";
18
+ /** Custom HTTP client configured. */
19
+ SdkTelemetryFeature["CUSTOM_TRANSPORT"] = "ct";
20
+ /** Retries enabled on the client. */
21
+ SdkTelemetryFeature["RETRY_CONFIG"] = "rc";
22
+ })(SdkTelemetryFeature || (exports.SdkTelemetryFeature = SdkTelemetryFeature = {}));
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ /*
3
+ * This file is auto-generated by Chargebee.
4
+ * For more information on how to make changes to this file, please see the README.
5
+ * Reach out to dx@chargebee.com for any questions.
6
+ * Copyright 2026 Chargebee Inc.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.SDK_TELEMETRY_FEATURES_KEY = exports.SDK_TELEMETRY_MAX_HEADER_BYTES = exports.SDK_TELEMETRY_HEADER_NAME = void 0;
10
+ /** Constants for the anonymous SDK telemetry request header. */
11
+ exports.SDK_TELEMETRY_HEADER_NAME = 'x-chargebee-sdk-telemetry';
12
+ /** Defensive size cap; feature-only values are tiny. */
13
+ exports.SDK_TELEMETRY_MAX_HEADER_BYTES = 4096;
14
+ /** RFC 9651 sf-list item name for the features segment. */
15
+ exports.SDK_TELEMETRY_FEATURES_KEY = 'f';
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /*
3
+ * This file is auto-generated by Chargebee.
4
+ * For more information on how to make changes to this file, please see the README.
5
+ * Reach out to dx@chargebee.com for any questions.
6
+ * Copyright 2026 Chargebee Inc.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.buildSdkTelemetryHeader = buildSdkTelemetryHeader;
10
+ const sdkTelemetryHeader_js_1 = require("./sdkTelemetryHeader.js");
11
+ /**
12
+ * Builds RFC 9651 values for {@link SDK_TELEMETRY_HEADER_NAME}: a features segment keyed by
13
+ * {@link SDK_TELEMETRY_FEATURES_KEY} with enabled feature codes as boolean params
14
+ * (for example {@code f;ta;rc}). Correlate SDK identity via User-Agent.
15
+ */
16
+ function buildSdkTelemetryHeader(features) {
17
+ if (!features || features.length === 0) {
18
+ return undefined;
19
+ }
20
+ let value = sdkTelemetryHeader_js_1.SDK_TELEMETRY_FEATURES_KEY;
21
+ for (const feature of features) {
22
+ if (feature == null) {
23
+ continue;
24
+ }
25
+ value += `;${feature}`;
26
+ }
27
+ if (value.length === sdkTelemetryHeader_js_1.SDK_TELEMETRY_FEATURES_KEY.length) {
28
+ return undefined;
29
+ }
30
+ if (new TextEncoder().encode(value).length > sdkTelemetryHeader_js_1.SDK_TELEMETRY_MAX_HEADER_BYTES) {
31
+ return undefined;
32
+ }
33
+ return value;
34
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ /*
3
+ * This file is auto-generated by Chargebee.
4
+ * For more information on how to make changes to this file, please see the README.
5
+ * Reach out to dx@chargebee.com for any questions.
6
+ * Copyright 2026 Chargebee Inc.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.SdkTelemetryState = void 0;
10
+ /**
11
+ * Per-client gate so the SDK telemetry header is considered at most once per client instance.
12
+ */
13
+ class SdkTelemetryState {
14
+ constructor() {
15
+ this.emitted = false;
16
+ }
17
+ /**
18
+ * Claims the single emission slot for this client. Returns true only for the first caller.
19
+ */
20
+ tryMarkEmitted() {
21
+ if (this.emitted) {
22
+ return false;
23
+ }
24
+ this.emitted = true;
25
+ return true;
26
+ }
27
+ /** Whether this client has already considered emitting the telemetry header. */
28
+ hasEmitted() {
29
+ return this.emitted;
30
+ }
31
+ /** Clears the emission gate (tests only). */
32
+ clear() {
33
+ this.emitted = false;
34
+ }
35
+ }
36
+ exports.SdkTelemetryState = SdkTelemetryState;
@@ -1,5 +1,5 @@
1
1
  import { extend, callbackifyPromise, getApiURL, encodeListParams, encodeParams, serialize, getHost, log, generateUUIDv4 as uuidv4, } from './util.js';
2
- import { buildRequestTelemetryContext, buildRequestTelemetryResult, extractHttpStatusCode, extractRequestTelemetryError, resolveChargebeeApiVersion, } from './telemetry/index.js';
2
+ import { buildRequestTelemetryContext, buildRequestTelemetryResult, extractHttpStatusCode, extractRequestTelemetryError, resolveChargebeeApiVersion, attachSdkTelemetryHeader, } from './telemetry/index.js';
3
3
  import { handleResponse } from './coreCommon.js';
4
4
  import { Buffer } from 'node:buffer';
5
5
  import { ChargebeeZodValidationError } from './chargebeeZodValidationError.js';
@@ -65,6 +65,15 @@ export class RequestWrapper {
65
65
  if (this.envArg.telemetryAdapter !== undefined) {
66
66
  _env.telemetryAdapter = this.envArg.telemetryAdapter;
67
67
  }
68
+ if (this.envArg.sdkTelemetryState !== undefined) {
69
+ _env.sdkTelemetryState = this.envArg.sdkTelemetryState;
70
+ }
71
+ if (this.envArg.sdkTelemetryEnabled !== undefined) {
72
+ _env.sdkTelemetryEnabled = this.envArg.sdkTelemetryEnabled;
73
+ }
74
+ if (this.envArg.httpClientIsCustom !== undefined) {
75
+ _env.httpClientIsCustom = this.envArg.httpClientIsCustom;
76
+ }
68
77
  const env = _env;
69
78
  const retryConfig = Object.assign({ enabled: false, maxRetries: 3, delayMs: 200, retryOn: [500, 502, 503, 504] }, env.retryConfig);
70
79
  const urlIdParam = this.apiCall.hasIdInUrl ? this.args[0] : null;
@@ -139,6 +148,7 @@ export class RequestWrapper {
139
148
  : encodeParams(requestParams, undefined, undefined, undefined, jsonKeys);
140
149
  }
141
150
  const requestHeaders = Object.assign(Object.assign({}, this.httpHeaders), telemetryHeaders);
151
+ attachSdkTelemetryHeader(env, requestHeaders);
142
152
  const contentType = this.apiCall.isJsonRequest
143
153
  ? 'application/json;charset=UTF-8'
144
154
  : 'application/x-www-form-urlencoded; charset=utf-8';
@@ -261,9 +271,10 @@ export class RequestWrapper {
261
271
  throw err;
262
272
  }
263
273
  };
264
- const promise = telemetryAdapter !== undefined
274
+ const executeCall = () => telemetryAdapter !== undefined
265
275
  ? runWithTelemetry(telemetryAdapter)
266
276
  : withRetry(0, requestStartTime);
277
+ const promise = executeCall();
267
278
  return callbackifyPromise(promise);
268
279
  }
269
280
  _createHeaders(httpHeaders) {
@@ -7,6 +7,6 @@ export default Chargebee;
7
7
  export { WebhookEventType, WebhookContentType, } from './resources/webhook/handler.js';
8
8
  export { basicAuthValidator } from './resources/webhook/auth.js';
9
9
  export { WebhookError, WebhookAuthenticationError, WebhookPayloadValidationError, WebhookPayloadParseError, } from './resources/webhook/handler.js';
10
- export { TelemetryAttributeKeys } from './telemetry/index.js';
10
+ export { TelemetryAttributeKeys, SDK_TELEMETRY_HEADER_NAME, } from './telemetry/index.js';
11
11
  // Export validation error class
12
12
  export { ChargebeeZodValidationError } from './chargebeeZodValidationError.js';
@@ -15,14 +15,18 @@ import { Endpoints } from './resources/api_endpoints.js';
15
15
  import { extend, sleep } from './util.js';
16
16
  import { waitForProcessToComplete } from './asyncApiSupport.js';
17
17
  import { WebhookHandler, createDefaultHandler, } from './resources/webhook/handler.js';
18
+ import { SdkTelemetryState } from './telemetry/index.js';
18
19
  export const CreateChargebee = (httpClient) => {
19
20
  const Chargebee = function (conf) {
20
21
  this._env = Object.assign({}, Environment);
21
- const { telemetryAdapter, httpClient: configHttpClient } = conf, confToMerge = __rest(conf, ["telemetryAdapter", "httpClient"]);
22
+ const { telemetryAdapter, httpClient: configHttpClient, sdkTelemetryEnabled } = conf, confToMerge = __rest(conf, ["telemetryAdapter", "httpClient", "sdkTelemetryEnabled"]);
22
23
  extend(true, this._env, confToMerge);
23
24
  // @ts-ignore
24
25
  this._env.httpClient =
25
26
  configHttpClient != null ? configHttpClient : httpClient;
27
+ this._env.sdkTelemetryState = new SdkTelemetryState();
28
+ this._env.sdkTelemetryEnabled = sdkTelemetryEnabled !== false;
29
+ this._env.httpClientIsCustom = configHttpClient != null;
26
30
  if (telemetryAdapter !== undefined) {
27
31
  this._env.telemetryAdapter = telemetryAdapter;
28
32
  }
@@ -8,7 +8,7 @@ export const Environment = {
8
8
  hostSuffix: '.chargebee.com',
9
9
  apiPath: '/api/v2',
10
10
  timeout: DEFAULT_TIME_OUT,
11
- clientVersion: 'v3.31.0',
11
+ clientVersion: 'v3.32.0',
12
12
  port: DEFAULT_PORT,
13
13
  timemachineWaitInMillis: DEFAULT_TIME_MACHINE_WAIT,
14
14
  exportWaitInMillis: DEFAULT_EXPORT_WAIT,
@@ -6,3 +6,8 @@
6
6
  */
7
7
  export { CHARGEBEE_SDK_NAME, CHARGEBEE_TELEMETRY_HEADER_EXCLUDE_PREFIX, CHARGEBEE_TELEMETRY_HEADER_PREFIX, HTTP_REQUEST_HEADER_ATTRIBUTE_PREFIX, TELEMETRY_SPAN_NAME_PREFIX, TelemetryAttributeKeys, } from './types.js';
8
8
  export { NO_OP_TELEMETRY_ADAPTER, NoOpTelemetryAdapter, buildRequestEndSpanAttributes, buildRequestHeaderSpanAttributes, buildRequestStartSpanAttributes, buildRequestTelemetryContext, buildRequestTelemetryResult, buildSpanName, extractHttpStatusCode, extractRequestTelemetryError, resolveChargebeeApiVersion, } from './TelemetryAdapter.js';
9
+ export { SDK_TELEMETRY_FEATURES_KEY, SDK_TELEMETRY_HEADER_NAME, SDK_TELEMETRY_MAX_HEADER_BYTES, } from './sdkTelemetryHeader.js';
10
+ export { SdkTelemetryFeature } from './sdkTelemetryFeature.js';
11
+ export { SdkTelemetryState } from './sdkTelemetryState.js';
12
+ export { buildSdkTelemetryHeader } from './sdkTelemetryHeaderBuilder.js';
13
+ export { attachSdkTelemetryHeader, } from './sdkTelemetryEmitter.js';
@@ -0,0 +1,61 @@
1
+ /*
2
+ * This file is auto-generated by Chargebee.
3
+ * For more information on how to make changes to this file, please see the README.
4
+ * Reach out to dx@chargebee.com for any questions.
5
+ * Copyright 2026 Chargebee Inc.
6
+ */
7
+ import { buildSdkTelemetryHeader } from './sdkTelemetryHeaderBuilder.js';
8
+ import { SdkTelemetryFeature } from './sdkTelemetryFeature.js';
9
+ import { SDK_TELEMETRY_HEADER_NAME } from './sdkTelemetryHeader.js';
10
+ /**
11
+ * Emits the anonymous SDK telemetry request header, independently of any customer telemetry
12
+ * adapter.
13
+ *
14
+ * On the first API call of a client instance, attaches {@code f;…} with enabled feature codes when
15
+ * any are present; omits the header when none are enabled. Later calls on the same client never
16
+ * attach again. SDK identity is correlated via User-Agent. Every failure path is swallowed and
17
+ * logged at WARNING: telemetry must never fail an API call.
18
+ */
19
+ export function attachSdkTelemetryHeader(env, headers) {
20
+ var _a;
21
+ if (env.sdkTelemetryEnabled === false) {
22
+ return;
23
+ }
24
+ try {
25
+ if (!((_a = env.sdkTelemetryState) === null || _a === void 0 ? void 0 : _a.tryMarkEmitted())) {
26
+ return;
27
+ }
28
+ const headerValue = buildSdkTelemetryHeader(resolveFeatures(env));
29
+ if (!headerValue) {
30
+ return;
31
+ }
32
+ headers[SDK_TELEMETRY_HEADER_NAME] = headerValue;
33
+ }
34
+ catch (err) {
35
+ logSuppressed('attach header', err);
36
+ }
37
+ }
38
+ /** Collects enabled feature codes for the current client configuration. */
39
+ function resolveFeatures(env) {
40
+ const features = [];
41
+ if (env.telemetryAdapter !== undefined) {
42
+ features.push(SdkTelemetryFeature.TELEMETRY_ADAPTER);
43
+ }
44
+ if (env.httpClientIsCustom) {
45
+ features.push(SdkTelemetryFeature.CUSTOM_TRANSPORT);
46
+ }
47
+ if (isRetryConfigActive(env)) {
48
+ features.push(SdkTelemetryFeature.RETRY_CONFIG);
49
+ }
50
+ return features;
51
+ }
52
+ /** Whether retries are enabled on the client. */
53
+ function isRetryConfigActive(env) {
54
+ var _a;
55
+ return ((_a = env.retryConfig) === null || _a === void 0 ? void 0 : _a.enabled) === true;
56
+ }
57
+ /** Logs a suppressed telemetry failure without affecting the API call. */
58
+ function logSuppressed(step, err) {
59
+ const message = err instanceof Error ? err.message : String(err);
60
+ console.warn(`SDK telemetry could not ${step} (${message}); API call unaffected.`, err);
61
+ }
@@ -0,0 +1,19 @@
1
+ /*
2
+ * This file is auto-generated by Chargebee.
3
+ * For more information on how to make changes to this file, please see the README.
4
+ * Reach out to dx@chargebee.com for any questions.
5
+ * Copyright 2026 Chargebee Inc.
6
+ */
7
+ /**
8
+ * SDK configuration features reported under the {@code f} segment of
9
+ * {@link SDK_TELEMETRY_HEADER_NAME}. Wire codes are maintained in sdk-generator.
10
+ */
11
+ export var SdkTelemetryFeature;
12
+ (function (SdkTelemetryFeature) {
13
+ /** Customer TelemetryAdapter configured. */
14
+ SdkTelemetryFeature["TELEMETRY_ADAPTER"] = "ta";
15
+ /** Custom HTTP client configured. */
16
+ SdkTelemetryFeature["CUSTOM_TRANSPORT"] = "ct";
17
+ /** Retries enabled on the client. */
18
+ SdkTelemetryFeature["RETRY_CONFIG"] = "rc";
19
+ })(SdkTelemetryFeature || (SdkTelemetryFeature = {}));
@@ -0,0 +1,12 @@
1
+ /*
2
+ * This file is auto-generated by Chargebee.
3
+ * For more information on how to make changes to this file, please see the README.
4
+ * Reach out to dx@chargebee.com for any questions.
5
+ * Copyright 2026 Chargebee Inc.
6
+ */
7
+ /** Constants for the anonymous SDK telemetry request header. */
8
+ export const SDK_TELEMETRY_HEADER_NAME = 'x-chargebee-sdk-telemetry';
9
+ /** Defensive size cap; feature-only values are tiny. */
10
+ export const SDK_TELEMETRY_MAX_HEADER_BYTES = 4096;
11
+ /** RFC 9651 sf-list item name for the features segment. */
12
+ export const SDK_TELEMETRY_FEATURES_KEY = 'f';
@@ -0,0 +1,31 @@
1
+ /*
2
+ * This file is auto-generated by Chargebee.
3
+ * For more information on how to make changes to this file, please see the README.
4
+ * Reach out to dx@chargebee.com for any questions.
5
+ * Copyright 2026 Chargebee Inc.
6
+ */
7
+ import { SDK_TELEMETRY_FEATURES_KEY, SDK_TELEMETRY_MAX_HEADER_BYTES, } from './sdkTelemetryHeader.js';
8
+ /**
9
+ * Builds RFC 9651 values for {@link SDK_TELEMETRY_HEADER_NAME}: a features segment keyed by
10
+ * {@link SDK_TELEMETRY_FEATURES_KEY} with enabled feature codes as boolean params
11
+ * (for example {@code f;ta;rc}). Correlate SDK identity via User-Agent.
12
+ */
13
+ export function buildSdkTelemetryHeader(features) {
14
+ if (!features || features.length === 0) {
15
+ return undefined;
16
+ }
17
+ let value = SDK_TELEMETRY_FEATURES_KEY;
18
+ for (const feature of features) {
19
+ if (feature == null) {
20
+ continue;
21
+ }
22
+ value += `;${feature}`;
23
+ }
24
+ if (value.length === SDK_TELEMETRY_FEATURES_KEY.length) {
25
+ return undefined;
26
+ }
27
+ if (new TextEncoder().encode(value).length > SDK_TELEMETRY_MAX_HEADER_BYTES) {
28
+ return undefined;
29
+ }
30
+ return value;
31
+ }
@@ -0,0 +1,32 @@
1
+ /*
2
+ * This file is auto-generated by Chargebee.
3
+ * For more information on how to make changes to this file, please see the README.
4
+ * Reach out to dx@chargebee.com for any questions.
5
+ * Copyright 2026 Chargebee Inc.
6
+ */
7
+ /**
8
+ * Per-client gate so the SDK telemetry header is considered at most once per client instance.
9
+ */
10
+ export class SdkTelemetryState {
11
+ constructor() {
12
+ this.emitted = false;
13
+ }
14
+ /**
15
+ * Claims the single emission slot for this client. Returns true only for the first caller.
16
+ */
17
+ tryMarkEmitted() {
18
+ if (this.emitted) {
19
+ return false;
20
+ }
21
+ this.emitted = true;
22
+ return true;
23
+ }
24
+ /** Whether this client has already considered emitting the telemetry header. */
25
+ hasEmitted() {
26
+ return this.emitted;
27
+ }
28
+ /** Clears the emission gate (tests only). */
29
+ clear() {
30
+ this.emitted = false;
31
+ }
32
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chargebee",
3
- "version": "3.31.0",
3
+ "version": "3.32.0",
4
4
  "description": "A library for integrating with Chargebee.",
5
5
  "scripts": {
6
6
  "prepack": "npm ci && npm run build",
@@ -8,7 +8,8 @@
8
8
  "build": "npm run build-esm && npm run build-cjs",
9
9
  "build-esm": "rm -rf esm && mkdir -p esm && tsc -p tsconfig.esm.json && echo '{\"type\":\"module\"}' > esm/package.json",
10
10
  "build-cjs": "rm -rf cjs && mkdir -p cjs && tsc -p tsconfig.cjs.json && echo '{\"type\":\"commonjs\"}' > cjs/package.json",
11
- "prettier": "prettier --write \"src/**/*.ts\" \"types/**/*.d.ts\""
11
+ "format": "biome format --write",
12
+ "format:check": "biome format"
12
13
  },
13
14
  "types": "./types/index.d.ts",
14
15
  "keywords": [
@@ -76,22 +77,17 @@
76
77
  }
77
78
  },
78
79
  "devDependencies": {
80
+ "@biomejs/biome": "^2.5.7",
79
81
  "@opentelemetry/api": "^1.9.0",
80
82
  "@types/chai": "^4.3.5",
81
83
  "@types/mocha": "^10.0.10",
82
84
  "@types/node": "20.12.0",
83
85
  "chai": "^4.3.7",
84
86
  "mocha": "^10.2.0",
85
- "prettier": "^3.3.3",
86
87
  "ts-node": "^10.9.1",
87
88
  "typescript": "^5.5.4",
88
89
  "undici-types": "^7.16.0"
89
90
  },
90
- "prettier": {
91
- "semi": true,
92
- "singleQuote": true,
93
- "parser": "typescript"
94
- },
95
91
  "dependencies": {
96
92
  "zod": "^4.3.6"
97
93
  }
package/types/index.d.ts CHANGED
@@ -189,14 +189,17 @@ declare module 'chargebee' {
189
189
  * @telemetryAdapter optional telemetry adapter for observability (e.g. OpenTelemetry)
190
190
  */
191
191
  telemetryAdapter?: TelemetryAdapter;
192
+
193
+ /**
194
+ * @sdkTelemetryEnabled when false, the SDK does not send the anonymous x-chargebee-sdk-telemetry header. Default true.
195
+ */
196
+ sdkTelemetryEnabled?: boolean;
192
197
  };
193
198
 
194
199
  export interface HttpClientInterface {
195
200
  makeApiRequest: (request: Request, timeout: number) => Promise<Response>;
196
201
  }
197
202
 
198
- export type RequestTelemetryHandle = unknown;
199
-
200
203
  export const TelemetryAttributeKeys: {
201
204
  readonly URL_FULL: 'url.full';
202
205
  readonly HTTP_REQUEST_METHOD: 'http.request.method';
@@ -214,6 +217,10 @@ declare module 'chargebee' {
214
217
  readonly CHARGEBEE_ERROR_PARAM: 'chargebee.error.param';
215
218
  };
216
219
 
220
+ export const SDK_TELEMETRY_HEADER_NAME: 'x-chargebee-sdk-telemetry';
221
+
222
+ export type RequestTelemetryHandle = unknown;
223
+
217
224
  export type RequestTelemetryContext = {
218
225
  spanName: string;
219
226
  resource: string;