autotel-subscribers 10.0.0 → 11.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
@@ -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
  };