autotel-subscribers 10.0.0 → 12.0.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/dist/index.d.cts CHANGED
@@ -4,7 +4,7 @@ export { SegmentConfig, SegmentSubscriber } from './segment.cjs';
4
4
  export { AmplitudeConfig, AmplitudeSubscriber } from './amplitude.cjs';
5
5
  export { SlackSubscriber, SlackSubscriberConfig } from './slack.cjs';
6
6
  export { WebhookConfig, WebhookSubscriber } from './webhook.cjs';
7
- import { E as EventSubscriber, a as EventPayload } from './event-subscriber-base-CnF3V56W.cjs';
7
+ import { E as EventSubscriber, a as EventPayload } from './event-subscriber-base-uT-C_zrL.cjs';
8
8
  import 'autotel/event-subscriber';
9
9
  import 'posthog-node';
10
10
 
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export { SegmentConfig, SegmentSubscriber } from './segment.js';
4
4
  export { AmplitudeConfig, AmplitudeSubscriber } from './amplitude.js';
5
5
  export { SlackSubscriber, SlackSubscriberConfig } from './slack.js';
6
6
  export { WebhookConfig, WebhookSubscriber } from './webhook.js';
7
- import { E as EventSubscriber, a as EventPayload } from './event-subscriber-base-CnF3V56W.js';
7
+ import { E as EventSubscriber, a as EventPayload } from './event-subscriber-base-uT-C_zrL.js';
8
8
  import 'autotel/event-subscriber';
9
9
  import 'posthog-node';
10
10
 
package/dist/index.js CHANGED
@@ -4599,7 +4599,7 @@ var require_dist = __commonJS({
4599
4599
  var http3 = __importStar(__require("http"));
4600
4600
  var https_1 = __require("https");
4601
4601
  __exportStar(require_helpers(), exports$1);
4602
- var INTERNAL2 = Symbol("AgentBaseInternalState");
4602
+ var INTERNAL2 = /* @__PURE__ */ Symbol("AgentBaseInternalState");
4603
4603
  var Agent = class extends http3.Agent {
4604
4604
  constructor(opts) {
4605
4605
  super(opts);
@@ -10078,8 +10078,8 @@ var require_utils3 = __commonJS({
10078
10078
  Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i]));
10079
10079
  }
10080
10080
  };
10081
- module.exports.wrapperSymbol = Symbol("wrapper");
10082
- module.exports.implSymbol = Symbol("impl");
10081
+ module.exports.wrapperSymbol = /* @__PURE__ */ Symbol("wrapper");
10082
+ module.exports.implSymbol = /* @__PURE__ */ Symbol("impl");
10083
10083
  module.exports.wrapperForImpl = function(impl) {
10084
10084
  return impl[module.exports.wrapperSymbol];
10085
10085
  };
@@ -10270,7 +10270,7 @@ var require_url_state_machine = __commonJS({
10270
10270
  ws: 80,
10271
10271
  wss: 443
10272
10272
  };
10273
- var failure = Symbol("failure");
10273
+ var failure = /* @__PURE__ */ Symbol("failure");
10274
10274
  function countSymbols(str) {
10275
10275
  return punycode.ucs2.decode(str).length;
10276
10276
  }
@@ -12283,8 +12283,8 @@ var init_lib = __esm({
12283
12283
  "../../node_modules/.pnpm/node-fetch@2.7.0/node_modules/node-fetch/lib/index.mjs"() {
12284
12284
  import_whatwg_url = __toESM(require_public_api());
12285
12285
  Readable = Stream.Readable;
12286
- BUFFER2 = Symbol("buffer");
12287
- TYPE = Symbol("type");
12286
+ BUFFER2 = /* @__PURE__ */ Symbol("buffer");
12287
+ TYPE = /* @__PURE__ */ Symbol("type");
12288
12288
  Blob2 = class _Blob {
12289
12289
  constructor() {
12290
12290
  this[TYPE] = "";
@@ -12389,7 +12389,7 @@ var init_lib = __esm({
12389
12389
  convert = __require("encoding").convert;
12390
12390
  } catch (e) {
12391
12391
  }
12392
- INTERNALS = Symbol("Body internals");
12392
+ INTERNALS = /* @__PURE__ */ Symbol("Body internals");
12393
12393
  PassThrough = Stream.PassThrough;
12394
12394
  Body.prototype = {
12395
12395
  get body() {
@@ -12492,7 +12492,7 @@ var init_lib = __esm({
12492
12492
  Body.Promise = global.Promise;
12493
12493
  invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/;
12494
12494
  invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
12495
- MAP = Symbol("map");
12495
+ MAP = /* @__PURE__ */ Symbol("map");
12496
12496
  Headers = class _Headers {
12497
12497
  /**
12498
12498
  * Headers class
@@ -12689,7 +12689,7 @@ var init_lib = __esm({
12689
12689
  values: { enumerable: true },
12690
12690
  entries: { enumerable: true }
12691
12691
  });
12692
- INTERNAL = Symbol("internal");
12692
+ INTERNAL = /* @__PURE__ */ Symbol("internal");
12693
12693
  HeadersIteratorPrototype = Object.setPrototypeOf({
12694
12694
  next() {
12695
12695
  if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) {
@@ -12718,7 +12718,7 @@ var init_lib = __esm({
12718
12718
  enumerable: false,
12719
12719
  configurable: true
12720
12720
  });
12721
- INTERNALS$1 = Symbol("Response internals");
12721
+ INTERNALS$1 = /* @__PURE__ */ Symbol("Response internals");
12722
12722
  STATUS_CODES = http__default.STATUS_CODES;
12723
12723
  Response2 = class _Response {
12724
12724
  constructor() {
@@ -12794,7 +12794,7 @@ var init_lib = __esm({
12794
12794
  enumerable: false,
12795
12795
  configurable: true
12796
12796
  });
12797
- INTERNALS$2 = Symbol("Request internals");
12797
+ INTERNALS$2 = /* @__PURE__ */ Symbol("Request internals");
12798
12798
  URL2 = Url.URL || import_whatwg_url.default.URL;
12799
12799
  parse_url = Url.parse;
12800
12800
  format_url = Url.format;
@@ -15396,6 +15396,35 @@ var EventSubscriber = class {
15396
15396
  payload
15397
15397
  );
15398
15398
  }
15399
+ /**
15400
+ * Filter out undefined and null values from attributes
15401
+ *
15402
+ * This improves DX by allowing callers to pass objects with optional properties
15403
+ * without having to manually filter them first.
15404
+ *
15405
+ * @param attributes - Input attributes (may contain undefined/null)
15406
+ * @returns Filtered attributes with only defined values, or undefined if empty
15407
+ *
15408
+ * @example
15409
+ * ```typescript
15410
+ * const filtered = this.filterAttributes({
15411
+ * userId: user.id,
15412
+ * email: user.email, // might be undefined
15413
+ * plan: null, // will be filtered out
15414
+ * });
15415
+ * // Result: { userId: 'abc', email: 'test@example.com' } or { userId: 'abc' }
15416
+ * ```
15417
+ */
15418
+ filterAttributes(attributes) {
15419
+ if (!attributes) return void 0;
15420
+ const filtered = {};
15421
+ for (const [key, value] of Object.entries(attributes)) {
15422
+ if (value !== void 0 && value !== null) {
15423
+ filtered[key] = value;
15424
+ }
15425
+ }
15426
+ return Object.keys(filtered).length > 0 ? filtered : void 0;
15427
+ }
15399
15428
  /**
15400
15429
  * Track an event
15401
15430
  */
@@ -15453,6 +15482,31 @@ var EventSubscriber = class {
15453
15482
  };
15454
15483
  await this.send(payload);
15455
15484
  }
15485
+ /**
15486
+ * Track funnel progression with custom step names
15487
+ *
15488
+ * Unlike trackFunnelStep which uses FunnelStatus enum values,
15489
+ * this method allows any string as the step name for flexible funnel tracking.
15490
+ *
15491
+ * @param funnelName - Name of the funnel (e.g., "checkout", "onboarding")
15492
+ * @param stepName - Custom step name (e.g., "cart_viewed", "payment_entered")
15493
+ * @param stepNumber - Optional numeric position in the funnel
15494
+ * @param attributes - Optional event attributes
15495
+ */
15496
+ async trackFunnelProgression(funnelName, stepName, stepNumber, attributes) {
15497
+ if (!this.enabled) return;
15498
+ const payload = {
15499
+ type: "funnel",
15500
+ name: `${funnelName}.${stepName}`,
15501
+ funnel: funnelName,
15502
+ step: stepName,
15503
+ stepName,
15504
+ stepNumber,
15505
+ attributes,
15506
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
15507
+ };
15508
+ await this.send(payload);
15509
+ }
15456
15510
  /**
15457
15511
  * Flush pending requests and clean up
15458
15512
  *
@@ -15513,19 +15567,47 @@ var PostHogSubscriber = class extends EventSubscriber {
15513
15567
  posthog = null;
15514
15568
  config;
15515
15569
  initPromise = null;
15570
+ /** True when using browser's window.posthog (different API signature) */
15571
+ isBrowserClient = false;
15516
15572
  constructor(config) {
15517
15573
  super();
15518
- if (!config.apiKey && !config.client) {
15519
- throw new Error("PostHogSubscriber requires either apiKey or client to be provided");
15574
+ if (config.serverless) {
15575
+ config = {
15576
+ flushAt: 1,
15577
+ flushInterval: 0,
15578
+ requestTimeout: 3e3,
15579
+ ...config
15580
+ // User config overrides serverless defaults
15581
+ };
15582
+ }
15583
+ if (!config.apiKey && !config.client && !config.useGlobalClient) {
15584
+ throw new Error(
15585
+ "PostHogSubscriber requires either apiKey, client, or useGlobalClient to be provided"
15586
+ );
15520
15587
  }
15521
15588
  this.enabled = config.enabled ?? true;
15522
- this.config = config;
15589
+ this.config = {
15590
+ filterUndefinedValues: true,
15591
+ ...config
15592
+ };
15523
15593
  if (this.enabled) {
15524
15594
  this.initPromise = this.initialize();
15525
15595
  }
15526
15596
  }
15527
15597
  async initialize() {
15528
15598
  try {
15599
+ if (this.config.useGlobalClient) {
15600
+ const globalWindow = typeof globalThis === "undefined" ? void 0 : globalThis;
15601
+ if (globalWindow?.posthog) {
15602
+ this.posthog = globalWindow.posthog;
15603
+ this.isBrowserClient = true;
15604
+ this.setupErrorHandling();
15605
+ return;
15606
+ }
15607
+ throw new Error(
15608
+ "useGlobalClient enabled but window.posthog not found. Ensure PostHog script is loaded before initializing the subscriber."
15609
+ );
15610
+ }
15529
15611
  if (this.config.client) {
15530
15612
  this.posthog = this.config.client;
15531
15613
  this.setupErrorHandling();
@@ -15572,19 +15654,31 @@ var PostHogSubscriber = class extends EventSubscriber {
15572
15654
  */
15573
15655
  async sendToDestination(payload) {
15574
15656
  await this.ensureInitialized();
15575
- let properties = payload.attributes;
15657
+ const filteredAttributes = this.config.filterUndefinedValues === false ? payload.attributes : this.filterAttributes(payload.attributes);
15658
+ const properties = { ...filteredAttributes };
15576
15659
  if (payload.value !== void 0) {
15577
- properties = { ...payload.attributes, value: payload.value };
15660
+ properties.value = payload.value;
15578
15661
  }
15579
- const capturePayload = {
15580
- distinctId: this.extractDistinctId(payload.attributes),
15581
- event: payload.name,
15582
- properties
15583
- };
15584
- if (payload.attributes?.groups) {
15585
- capturePayload.groups = payload.attributes.groups;
15662
+ if (payload.stepNumber !== void 0) {
15663
+ properties.step_number = payload.stepNumber;
15664
+ }
15665
+ if (payload.stepName !== void 0) {
15666
+ properties.step_name = payload.stepName;
15667
+ }
15668
+ const distinctId = this.extractDistinctId(filteredAttributes);
15669
+ if (this.isBrowserClient) {
15670
+ this.posthog?.capture(payload.name, properties);
15671
+ } else {
15672
+ const capturePayload = {
15673
+ distinctId,
15674
+ event: payload.name,
15675
+ properties
15676
+ };
15677
+ if (filteredAttributes?.groups) {
15678
+ capturePayload.groups = filteredAttributes.groups;
15679
+ }
15680
+ this.posthog?.capture(capturePayload);
15586
15681
  }
15587
- this.posthog?.capture(capturePayload);
15588
15682
  }
15589
15683
  // Feature Flag Methods
15590
15684
  /**
@@ -15806,6 +15900,15 @@ var PostHogSubscriber = class extends EventSubscriber {
15806
15900
  */
15807
15901
  handleError(error, payload) {
15808
15902
  this.config.onError?.(error);
15903
+ if (this.config.onErrorWithContext) {
15904
+ this.config.onErrorWithContext({
15905
+ error,
15906
+ eventName: payload.name,
15907
+ eventType: payload.type,
15908
+ attributes: payload.attributes,
15909
+ subscriberName: this.name
15910
+ });
15911
+ }
15809
15912
  super.handleError(error, payload);
15810
15913
  }
15811
15914
  };