@stacksee/analytics 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,220 @@
1
+ import { r as O, a as P, b as E } from "./axios-gULqh8dv.js";
2
+ function j(f, p) {
3
+ for (var d = 0; d < p.length; d++) {
4
+ const o = p[d];
5
+ if (typeof o != "string" && !Array.isArray(o)) {
6
+ for (const a in o)
7
+ if (a !== "default" && !(a in f)) {
8
+ const u = Object.getOwnPropertyDescriptor(o, a);
9
+ u && Object.defineProperty(f, a, u.get ? u : {
10
+ enumerable: !0,
11
+ get: () => o[a]
12
+ });
13
+ }
14
+ }
15
+ }
16
+ return Object.freeze(Object.defineProperty(f, Symbol.toStringTag, { value: "Module" }));
17
+ }
18
+ var r = {}, w;
19
+ function C() {
20
+ if (w) return r;
21
+ w = 1;
22
+ var f = r && r.__createBinding || (Object.create ? function(c, e, t, n) {
23
+ n === void 0 && (n = t);
24
+ var i = Object.getOwnPropertyDescriptor(e, t);
25
+ (!i || ("get" in i ? !e.__esModule : i.writable || i.configurable)) && (i = { enumerable: !0, get: function() {
26
+ return e[t];
27
+ } }), Object.defineProperty(c, n, i);
28
+ } : function(c, e, t, n) {
29
+ n === void 0 && (n = t), c[n] = e[t];
30
+ }), p = r && r.__setModuleDefault || (Object.create ? function(c, e) {
31
+ Object.defineProperty(c, "default", { enumerable: !0, value: e });
32
+ } : function(c, e) {
33
+ c.default = e;
34
+ }), d = r && r.__importStar || /* @__PURE__ */ function() {
35
+ var c = function(e) {
36
+ return c = Object.getOwnPropertyNames || function(t) {
37
+ var n = [];
38
+ for (var i in t) Object.prototype.hasOwnProperty.call(t, i) && (n[n.length] = i);
39
+ return n;
40
+ }, c(e);
41
+ };
42
+ return function(e) {
43
+ if (e && e.__esModule) return e;
44
+ var t = {};
45
+ if (e != null) for (var n = c(e), i = 0; i < n.length; i++) n[i] !== "default" && f(t, e, n[i]);
46
+ return p(t, e), t;
47
+ };
48
+ }(), o = r && r.__awaiter || function(c, e, t, n) {
49
+ function i(s) {
50
+ return s instanceof t ? s : new t(function(l) {
51
+ l(s);
52
+ });
53
+ }
54
+ return new (t || (t = Promise))(function(s, l) {
55
+ function g(h) {
56
+ try {
57
+ b(n.next(h));
58
+ } catch (v) {
59
+ l(v);
60
+ }
61
+ }
62
+ function y(h) {
63
+ try {
64
+ b(n.throw(h));
65
+ } catch (v) {
66
+ l(v);
67
+ }
68
+ }
69
+ function b(h) {
70
+ h.done ? s(h.value) : i(h.value).then(g, y);
71
+ }
72
+ b((n = n.apply(c, e || [])).next());
73
+ });
74
+ };
75
+ Object.defineProperty(r, "__esModule", { value: !0 }), r.Client = r.Pirsch = r.PirschWebClient = void 0;
76
+ const a = O(), u = P(), m = d(/* @__PURE__ */ E());
77
+ class _ extends a.PirschCommon {
78
+ /**
79
+ * The constructor creates a new client.
80
+ *
81
+ * @param {object} configuration You need to pass in the **Identification Code** you have configured on the Pirsch dashboard.
82
+ * It's also recommended to set the proper protocol for your website, else it will be set to `https` by default.
83
+ * All other configuration parameters can be left to their defaults.
84
+ * @param {string} configuration.baseUrl The base URL for the pirsch API
85
+ * @param {number} configuration.timeout The default HTTP timeout in milliseconds
86
+ * @param {string} configuration.identificationCode The identification code
87
+ * @param {string} configuration.hostname The hostname to rewrite the URL. Usually only required for testing
88
+ *
89
+ */
90
+ constructor(e) {
91
+ if (super(), "clientId" in e || "clientSecret" in e)
92
+ throw new Error("Do not pass OAuth secrets such as 'clientId' or 'clientSecret' to the web client!");
93
+ if ("accessToken" in e)
94
+ throw new Error("Do not pass secrets such as 'accessToken' to the web client!");
95
+ const { baseUrl: t = u.PIRSCH_DEFAULT_BASE_URL, timeout: n = u.PIRSCH_DEFAULT_TIMEOUT, identificationCode: i, hostname: s } = e;
96
+ this.assertIdentificationCodeCredentials({ identificationCode: i }), this.baseUrl = t, this.timeout = n, this.identificationCode = i, this.hostname = s, this.httpClient = m.default.create({ baseURL: this.baseUrl, timeout: this.timeout });
97
+ }
98
+ /**
99
+ * hit sends a hit to Pirsch.
100
+ *
101
+ * @param hit optional override data for the request.
102
+ */
103
+ hit(e) {
104
+ return o(this, void 0, void 0, function* () {
105
+ const t = Object.assign(Object.assign({}, this.hitFromBrowser()), e), n = this.browserHitToGetParameters(t);
106
+ yield this.get(u.PirschEndpoint.HIT, { parameters: n });
107
+ });
108
+ }
109
+ /**
110
+ * event sends an event to Pirsch.
111
+ *
112
+ * @param name the name for the event
113
+ * @param duration optional duration for the event
114
+ * @param meta optional object containing metadata (only scalar values, like strings, numbers, and booleans)
115
+ * @param hit optional override data for the request
116
+ */
117
+ event(e) {
118
+ return o(this, arguments, void 0, function* (t, n = 0, i, s) {
119
+ const l = Object.assign(Object.assign({}, this.hitFromBrowser()), s);
120
+ return this.beacon(u.PirschEndpoint.EVENT, Object.assign({ identification_code: this.identificationCode, event_name: t, event_duration: n, event_meta: this.prepareScalarObject(i) }, l)), Promise.resolve();
121
+ });
122
+ }
123
+ /**
124
+ * customHit sends a hit to Pirsch.
125
+ *
126
+ * @param hit data for the request.
127
+ */
128
+ customHit(e) {
129
+ return o(this, void 0, void 0, function* () {
130
+ const t = this.browserHitToGetParameters(e);
131
+ yield this.get(u.PirschEndpoint.HIT, { parameters: t });
132
+ });
133
+ }
134
+ /**
135
+ * customEvent sends an event to Pirsch.
136
+ *
137
+ * @param name the name for the event
138
+ * @param duration optional duration for the event
139
+ * @param hit data for the request
140
+ * @param meta optional object containing metadata (only scalar values, like strings, numbers, and booleans)
141
+ */
142
+ customEvent(e) {
143
+ return o(this, arguments, void 0, function* (t, n = 0, i, s) {
144
+ return this.beacon(u.PirschEndpoint.EVENT, Object.assign({ identification_code: this.identificationCode, event_name: t, event_duration: n, event_meta: this.prepareScalarObject(s) }, i)), Promise.resolve();
145
+ });
146
+ }
147
+ /**
148
+ * hitFromBrowser returns the required data to send a hit to Pirsch.
149
+ *
150
+ * @returns Hit object containing all necessary fields.
151
+ */
152
+ hitFromBrowser() {
153
+ return {
154
+ url: this.generateUrl(),
155
+ title: document.title,
156
+ referrer: document.referrer,
157
+ screen_width: screen.width,
158
+ screen_height: screen.height
159
+ };
160
+ }
161
+ browserHitToGetParameters(e) {
162
+ const t = {
163
+ nc: Date.now(),
164
+ code: this.identificationCode,
165
+ url: e.url
166
+ };
167
+ if (e.title && (t.t = e.title), e.referrer && (t.ref = e.referrer), e.screen_width && (t.w = e.screen_width), e.screen_height && (t.h = e.screen_height), e.tags)
168
+ for (const [n, i] of Object.entries(e.tags))
169
+ t[`tag_${n.replaceAll("-", " ")}`] = i || 1;
170
+ return t;
171
+ }
172
+ generateUrl() {
173
+ return (this.hostname ? location.href.replace(location.hostname, this.hostname) : location.href).slice(0, u.PIRSCH_URL_LENGTH_LIMIT);
174
+ }
175
+ get(e, t) {
176
+ return o(this, void 0, void 0, function* () {
177
+ try {
178
+ return (yield this.httpClient.get(e, this.createOptions(Object.assign({}, t)))).data;
179
+ } catch (n) {
180
+ throw yield this.toApiError(n);
181
+ }
182
+ });
183
+ }
184
+ post(e, t, n) {
185
+ return o(this, void 0, void 0, function* () {
186
+ try {
187
+ return (yield this.httpClient.post(e, t, this.createOptions(n ?? {}))).data;
188
+ } catch (i) {
189
+ throw yield this.toApiError(i);
190
+ }
191
+ });
192
+ }
193
+ beacon(e, t) {
194
+ return o(this, void 0, void 0, function* () {
195
+ if (!navigator.sendBeacon([this.baseUrl, e].join("/"), JSON.stringify(t)))
196
+ throw yield this.toApiError("sendBeacon failed");
197
+ });
198
+ }
199
+ toApiError(e) {
200
+ return o(this, void 0, void 0, function* () {
201
+ var t, n, i, s, l;
202
+ return e instanceof a.PirschApiError ? e : e instanceof m.AxiosError ? new a.PirschApiError((n = (t = e.response) === null || t === void 0 ? void 0 : t.status) !== null && n !== void 0 ? n : 400, (i = e.response) === null || i === void 0 ? void 0 : i.data) : typeof e == "object" && e !== null && "response" in e && typeof e.response == "object" && e.response !== null && "status" in e.response && "data" in e.response ? new a.PirschApiError((s = e.response.status) !== null && s !== void 0 ? s : 400, (l = e.response) === null || l === void 0 ? void 0 : l.data) : e instanceof Error ? new a.PirschUnknownApiError(e.message) : typeof e == "object" && e !== null && "message" in e && typeof e.message == "string" ? new a.PirschUnknownApiError(e.message) : new a.PirschUnknownApiError(JSON.stringify(e));
203
+ });
204
+ }
205
+ createOptions({ headers: e, parameters: t }) {
206
+ return {
207
+ headers: e,
208
+ params: t
209
+ };
210
+ }
211
+ }
212
+ return r.PirschWebClient = _, r.Pirsch = _, r.Client = _, r;
213
+ }
214
+ var A = C();
215
+ const U = /* @__PURE__ */ j({
216
+ __proto__: null
217
+ }, [A]);
218
+ export {
219
+ U as w
220
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stacksee/analytics",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "A highly typed, provider-agnostic analytics library for TypeScript applications",
5
5
  "type": "module",
6
6
  "exports": {
@@ -61,6 +61,8 @@
61
61
  "vitest": "^2.0.3"
62
62
  },
63
63
  "optionalDependencies": {
64
+ "@bentonow/bento-node-sdk": "^0.2.1",
65
+ "pirsch-sdk": "^2.9.1",
64
66
  "posthog-js": "^1.268.2",
65
67
  "posthog-node": "^5.9.0"
66
68
  },
package/readme.md CHANGED
@@ -5,6 +5,7 @@ A highly typed, zero-dependency, provider-agnostic analytics library for TypeScr
5
5
  ## Table of Contents
6
6
 
7
7
  - [Features](#features)
8
+ - [Providers](#providers)
8
9
  - [Installation](#installation)
9
10
  - [Quick Start](#quick-start)
10
11
  - [1. Define Your Events](#1-define-your-events)
@@ -44,6 +45,35 @@ A highly typed, zero-dependency, provider-agnostic analytics library for TypeScr
44
45
  - 🌎 **Edge ready**: The server client is compatible with edge runtime (e.g. Cloudflare Workers, Vercel Edge functions)
45
46
  - 🔧 **Extensible**: Simple interface to add new providers
46
47
 
48
+ ## Providers
49
+
50
+ The library includes built-in support for popular analytics services, with more coming soon:
51
+
52
+ ### Official Providers
53
+
54
+ | Provider | Type | Documentation |
55
+ |----------|------|---------------|
56
+ | **PostHog** | Product Analytics | [docs/providers/posthog.md](./docs/providers/posthog.md) |
57
+ | **Bento** | Email Marketing & Events | [docs/providers/bento.md](./docs/providers/bento.md) |
58
+ | **Pirsch** | Privacy-Focused Web Analytics | [docs/providers/pirsch.md](./docs/providers/pirsch.md) |
59
+
60
+ ### Community & Custom Providers
61
+
62
+ Want to use a different analytics service? Check out our guide:
63
+
64
+ **[Creating Custom Providers →](./docs/providers/custom-providers.md)**
65
+
66
+ You can easily create providers for:
67
+ - Google Analytics
68
+ - Mixpanel
69
+ - Amplitude
70
+ - Segment
71
+ - Customer.io
72
+ - Loops
73
+ - Any analytics service with a JavaScript SDK
74
+
75
+ **[View all provider documentation →](./docs/providers/)**
76
+
47
77
  ## Installation
48
78
 
49
79
  ```bash
@@ -51,8 +81,16 @@ pnpm install @stacksee/analytics
51
81
 
52
82
  # For PostHog support
53
83
  pnpm install posthog-js posthog-node
84
+
85
+ # For Bento support (server-side only)
86
+ pnpm install @bentonow/bento-node-sdk
87
+
88
+ # For Pirsch support
89
+ pnpm install pirsch-sdk
54
90
  ```
55
91
 
92
+ > **See also:** [Provider Documentation](./docs/providers/) for detailed setup guides for each provider.
93
+
56
94
  ## Quick Start
57
95
 
58
96
  ### 1. Define Your Events
@@ -705,32 +743,21 @@ export const appEvents = {
705
743
 
706
744
  ### Adding Custom Providers
707
745
 
708
- Implement the `AnalyticsProvider` interface to add support for other analytics services:
746
+ Want to integrate with a different analytics service? See our comprehensive guide:
747
+
748
+ **[Creating Custom Providers →](./docs/providers/custom-providers.md)**
749
+
750
+ Quick example:
709
751
 
710
752
  ```typescript
711
753
  import { BaseAnalyticsProvider, BaseEvent, EventContext } from '@stacksee/analytics';
712
754
 
713
755
  export class GoogleAnalyticsProvider extends BaseAnalyticsProvider {
714
756
  name = 'GoogleAnalytics';
715
- private measurementId: string;
716
-
717
- constructor(config: { measurementId: string; debug?: boolean; enabled?: boolean }) {
718
- super({ debug: config.debug, enabled: config.enabled });
719
- this.measurementId = config.measurementId;
720
- }
721
-
722
- async initialize(): Promise<void> {
723
- // Initialize GA
724
- }
725
-
726
- track(event: BaseEvent, context?: EventContext): void {
727
- // Send event to GA
728
- }
729
-
730
- identify(userId: string, traits?: Record<string, unknown>): void {
731
- // Set user properties in GA
732
- }
733
757
 
758
+ async initialize(): Promise<void> { /* Initialize GA */ }
759
+ track(event: BaseEvent, context?: EventContext): void { /* Track event */ }
760
+ identify(userId: string, traits?: Record<string, unknown>): void { /* Identify user */ }
734
761
  // ... implement other required methods
735
762
  }
736
763
  ```
@@ -738,9 +765,9 @@ export class GoogleAnalyticsProvider extends BaseAnalyticsProvider {
738
765
  Then use it as a plugin in your configuration:
739
766
 
740
767
  ```typescript
741
- const analytics = await createClientAnalytics<typeof AppEvents>({
768
+ const analytics = createClientAnalytics<typeof AppEvents>({
742
769
  providers: [
743
- new PostHogClientProvider({ apiKey: 'xxx' }),
770
+ new PostHogClientProvider({ token: 'xxx' }),
744
771
  new GoogleAnalyticsProvider({ measurementId: 'xxx' })
745
772
  ]
746
773
  });