@od-oneapp/analytics 2026.2.2301-canary → 2026.2.2899-canary

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.
Files changed (89) hide show
  1. package/README.md +126 -345
  2. package/catalogs.d.mts +1815 -0
  3. package/catalogs.d.mts.map +1 -0
  4. package/catalogs.mjs +437 -0
  5. package/catalogs.mjs.map +1 -0
  6. package/{chunk-DQk6qfdC.mjs → client-CMc1iZBB.mjs} +8 -1
  7. package/{client-DK8twEdp.mjs.map → client-CMc1iZBB.mjs.map} +1 -1
  8. package/client-next.d.mts +4 -8
  9. package/client-next.d.mts.map +1 -1
  10. package/client-next.mjs +134 -944
  11. package/client-next.mjs.map +1 -1
  12. package/client.d.mts +6 -25
  13. package/client.d.mts.map +1 -1
  14. package/client.mjs +24 -140
  15. package/client.mjs.map +1 -1
  16. package/{posthog-bootstrap-DkPdn-hA.mjs → config-BX38D_1T.mjs} +343 -44
  17. package/config-BX38D_1T.mjs.map +1 -0
  18. package/{posthog-bootstrap-Bu1BfhVv.d.mts → config-CSo5ZON1.d.mts} +32 -9
  19. package/config-CSo5ZON1.d.mts.map +1 -0
  20. package/{console-BpU88FNF.mjs → console-BAFQVsN6.mjs} +2 -4
  21. package/{console-BpU88FNF.mjs.map → console-BAFQVsN6.mjs.map} +1 -1
  22. package/{index-DTvdqV7H.d.mts → index-BYVvvAQ8.d.mts} +23 -39
  23. package/index-BYVvvAQ8.d.mts.map +1 -0
  24. package/load-provider-L0Smj7SY.d.mts +9 -0
  25. package/load-provider-L0Smj7SY.d.mts.map +1 -0
  26. package/load-provider-X2ADGRb5.mjs +112 -0
  27. package/load-provider-X2ADGRb5.mjs.map +1 -0
  28. package/{manager-OJpSKwqb.d.mts → manager-B0CnygV0.d.mts} +19 -3
  29. package/manager-B0CnygV0.d.mts.map +1 -0
  30. package/package.json +23 -27
  31. package/providers-http-client.d.mts +1 -1
  32. package/providers-http-server.d.mts +1 -1
  33. package/server-next.d.mts +6 -66
  34. package/server-next.mjs +4 -192
  35. package/server.d.mts +6 -10
  36. package/server.mjs +4 -6
  37. package/{service-NuHnv30x.mjs → service-BNIvrglv.mjs} +27 -270
  38. package/service-BNIvrglv.mjs.map +1 -0
  39. package/{types-cMMfHIpi.d.mts → types-C12o4SgZ.d.mts} +2 -87
  40. package/types-C12o4SgZ.d.mts.map +1 -0
  41. package/types.d.mts +3 -4
  42. package/types.mjs +3 -0
  43. package/validation-DSvytucA.mjs +258 -0
  44. package/validation-DSvytucA.mjs.map +1 -0
  45. package/ai-Co8hBoEj.mjs +0 -3347
  46. package/ai-Co8hBoEj.mjs.map +0 -1
  47. package/client-B8gfgflr.mjs +0 -267
  48. package/client-B8gfgflr.mjs.map +0 -1
  49. package/client-C35AzV71.mjs +0 -296
  50. package/client-C35AzV71.mjs.map +0 -1
  51. package/client-DDehaDSz.mjs +0 -54
  52. package/client-DDehaDSz.mjs.map +0 -1
  53. package/client-DK8twEdp.mjs +0 -9
  54. package/config-6Mwe7b2O.mjs +0 -287
  55. package/config-6Mwe7b2O.mjs.map +0 -1
  56. package/config-Ciu7O6n1.d.mts +0 -34
  57. package/config-Ciu7O6n1.d.mts.map +0 -1
  58. package/ecommerce-DGG1FbiH.mjs +0 -993
  59. package/ecommerce-DGG1FbiH.mjs.map +0 -1
  60. package/emitters-BDSsleo_.d.mts +0 -12
  61. package/emitters-BDSsleo_.d.mts.map +0 -1
  62. package/emitters-BvEelkxS.mjs +0 -208
  63. package/emitters-BvEelkxS.mjs.map +0 -1
  64. package/index-BWhDEs8u.d.mts +0 -184
  65. package/index-BWhDEs8u.d.mts.map +0 -1
  66. package/index-Cp-N57Zb.d.mts +0 -953
  67. package/index-Cp-N57Zb.d.mts.map +0 -1
  68. package/index-DTvdqV7H.d.mts.map +0 -1
  69. package/manager-OJpSKwqb.d.mts.map +0 -1
  70. package/module-DVAU7zKb.mjs +0 -5850
  71. package/module-DVAU7zKb.mjs.map +0 -1
  72. package/posthog-bootstrap-Bu1BfhVv.d.mts.map +0 -1
  73. package/posthog-bootstrap-DkPdn-hA.mjs.map +0 -1
  74. package/server-edge.d.mts +0 -9
  75. package/server-edge.d.mts.map +0 -1
  76. package/server-edge.mjs +0 -373
  77. package/server-edge.mjs.map +0 -1
  78. package/server-next.d.mts.map +0 -1
  79. package/server-next.mjs.map +0 -1
  80. package/service-NuHnv30x.mjs.map +0 -1
  81. package/shared.d.mts +0 -16
  82. package/shared.d.mts.map +0 -1
  83. package/shared.mjs +0 -93
  84. package/shared.mjs.map +0 -1
  85. package/types-DEcTnnFe.d.mts +0 -216
  86. package/types-DEcTnnFe.d.mts.map +0 -1
  87. package/types-cMMfHIpi.d.mts.map +0 -1
  88. package/vercel-types-oM7Sn385.d.mts +0 -102
  89. package/vercel-types-oM7Sn385.d.mts.map +0 -1
package/README.md CHANGED
@@ -1,91 +1,70 @@
1
- # @repo/analytics
1
+ # @od-oneapp/analytics
2
2
 
3
- > **Multi-provider analytics package with type-safe event tracking, comprehensive ecommerce support, and AI product
4
- > analytics**
3
+ > **Multi-provider analytics with Segment.io-style fan-out, type-safe event tracking, and Zod-validated catalogs**
5
4
 
6
5
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue.svg)](https://www.typescriptlang.org/)
7
6
  [![Node.js](https://img.shields.io/badge/Node.js-22+-green.svg)](https://nodejs.org/)
8
7
 
9
8
  ## Quick Reference
10
9
 
11
- **Status:** Development (Tests passing: 634/655, TypeCheck: ✅)
12
-
13
10
  **Requirements:**
14
11
 
15
- - Node.js 22.0.0+ (uses Node 22+ features: `structuredClone`, `AbortSignal.timeout`, bigint timing)
12
+ - Node.js 22.0.0+
16
13
  - pnpm 10.0.0+
17
14
  - Next.js 15.0.0+ (if using Next.js integration)
18
15
 
19
16
  **Exports:**
20
17
 
21
- - **Core**: `./client`, `./server`, `./shared`, `./types`
22
- - **Next.js**: `./client/next`, `./server/next`, `./server/edge`
18
+ - **Client**: `./client`, `./client/next`
19
+ - **Server**: `./server`, `./server/next`
20
+ - **Types**: `./types`
21
+ - **Catalogs**: `./catalogs`
22
+ - **HTTP Provider**: `./providers/http`, `./providers/http/client`, `./providers/http/server`
23
23
 
24
24
  **Key Features:**
25
25
 
26
- - Multi-Provider (PostHog, Vercel Analytics, Segment, Console)
27
- - Type-Safe Emitters (Segment.io specification)
28
- - Universal (client/server/edge environments)
29
- - E-commerce (50+ standardized events)
30
- - AI Product Tracking (90+ ChatGPT/Claude-style events)
31
- - Feature Flags (PostHog integration)
32
- - ✅ Next.js 15 (App Router, Server Components, hooks)
26
+ - Multi-Provider fan-out (PostHog, Segment, Vercel Analytics, HTTP, Console)
27
+ - Type-Safe Emitters (Segment.io specification)
28
+ - Zod-validated event catalogs (ecommerce, AI)
29
+ - Universal (client/server environments)
30
+ - Next.js App Router integration (hooks, components, provider)
31
+ - **Opt-in external providers** only install what you use
33
32
 
34
33
  ---
35
34
 
36
35
  ## Installation
37
36
 
38
- ### Prerequisites
39
-
40
- ⚠️ **Required:** Node.js 22+ (package uses `structuredClone`, `AbortSignal.timeout`, `process.hrtime.bigint`)
41
-
42
37
  ```bash
43
- # Check Node version
44
- node --version # Must be v22.0.0 or higher
45
-
46
- # Install package
47
- pnpm add @repo/analytics --filter=your-app
38
+ pnpm add @od-oneapp/analytics
48
39
  ```
49
40
 
50
- ### Install Providers (Peer Dependencies)
41
+ ### External Providers (opt-in)
51
42
 
52
- Install only the providers you need:
43
+ External analytics providers are **not bundled** with this package. Install only the ones you need:
53
44
 
54
45
  ```bash
55
- # PostHog (recommended - analytics + feature flags)
56
- pnpm add posthog-js posthog-node --filter=your-app
57
-
58
- # Vercel Analytics
59
- pnpm add @vercel/analytics --filter=your-app
46
+ # PostHog
47
+ pnpm add @od-oneapp/integration-posthog
60
48
 
61
49
  # Segment
62
- pnpm add @segment/analytics-next --filter=your-app
50
+ pnpm add @od-oneapp/integration-segment
63
51
 
64
- # Console (built-in, no installation needed)
52
+ # Vercel Analytics
53
+ pnpm add @od-oneapp/integration-vercel
65
54
  ```
66
55
 
67
- ---
68
-
69
- ## Quick Start
70
-
71
- ### Environment Variables
72
-
73
- ```bash
74
- # .env.local
56
+ Built-in providers (`console`, `http`) are always available with no additional installation.
75
57
 
76
- # PostHog (Primary)
77
- NEXT_PUBLIC_POSTHOG_KEY=phc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
78
- NEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.com
58
+ If you configure a provider without installing its package, you'll get a clear error:
79
59
 
80
- # Vercel Analytics (Optional)
81
- VERCEL_ANALYTICS_ID=your-analytics-id
60
+ ```
61
+ Analytics provider "posthog" is configured but its package is not installed.
62
+ Run: pnpm add @od-oneapp/integration-posthog
63
+ ```
82
64
 
83
- # Segment (Optional)
84
- NEXT_PUBLIC_SEGMENT_WRITE_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
65
+ ---
85
66
 
86
- # Development
87
- NEXT_PUBLIC_CONSOLE_ANALYTICS=true
88
- ```
67
+ ## Quick Start
89
68
 
90
69
  ### Next.js Setup
91
70
 
@@ -93,7 +72,7 @@ NEXT_PUBLIC_CONSOLE_ANALYTICS=true
93
72
  // app/providers.tsx
94
73
  "use client";
95
74
 
96
- import { AnalyticsProvider } from "@repo/analytics/client/next";
75
+ import { AnalyticsProvider } from "@od-oneapp/analytics/client/next";
97
76
 
98
77
  export function Providers({ children }: { children: React.ReactNode }) {
99
78
  return (
@@ -104,14 +83,14 @@ export function Providers({ children }: { children: React.ReactNode }) {
104
83
  apiKey: process.env.NEXT_PUBLIC_POSTHOG_KEY!,
105
84
  options: {
106
85
  debug: process.env.NODE_ENV === "development",
107
- capture_pageview: false
108
- }
86
+ capture_pageview: false,
87
+ },
109
88
  },
110
89
  console: {
111
- enabled: process.env.NODE_ENV === "development"
112
- }
90
+ enabled: process.env.NODE_ENV === "development",
91
+ },
113
92
  },
114
- debug: process.env.NODE_ENV === "development"
93
+ debug: process.env.NODE_ENV === "development",
115
94
  }}
116
95
  >
117
96
  {children}
@@ -120,118 +99,76 @@ export function Providers({ children }: { children: React.ReactNode }) {
120
99
  }
121
100
  ```
122
101
 
123
- ### Usage Examples
124
-
125
- #### Client Component
102
+ ### Client Component
126
103
 
127
104
  ```tsx
128
105
  "use client";
129
106
 
130
- import { useAnalytics, track } from "@repo/analytics/client/next";
107
+ import { useAnalytics, track } from "@od-oneapp/analytics/client/next";
131
108
 
132
109
  export function SignupButton() {
133
110
  const analytics = useAnalytics();
134
111
 
135
112
  const handleClick = async () => {
136
- // Method 1: Direct tracking
137
- await analytics.track("Button Clicked", { button_name: "signup" });
113
+ // Direct tracking
114
+ await analytics?.track("Button Clicked", { button_name: "signup" });
138
115
 
139
- // Method 2: Emitter pattern (recommended)
116
+ // Emitter pattern
140
117
  const event = track("CTA Clicked", { cta_type: "signup" });
141
- await analytics.emit(event);
118
+ await analytics?.emit(event);
142
119
  };
143
120
 
144
121
  return <button onClick={handleClick}>Sign Up</button>;
145
122
  }
146
123
  ```
147
124
 
148
- #### Server Component / API Route
125
+ ### Server (API Route)
149
126
 
150
- ```tsx
151
- // app/api/checkout/route.ts
152
- import { createServerAnalytics, ecommerce } from "@repo/analytics/server/next";
153
-
154
- export async function POST(request: Request) {
155
- const analytics = await createServerAnalytics({
156
- providers: {
157
- posthog: { apiKey: process.env.POSTHOG_API_KEY! }
158
- }
159
- });
127
+ ```typescript
128
+ import { createServerAnalytics } from "@od-oneapp/analytics/server";
160
129
 
161
- await analytics.emit(
162
- ecommerce.CHECKOUT_STARTED({
163
- order_id: "order_123",
164
- value: 299.99,
165
- currency: "USD",
166
- products: [{ product_id: "prod_abc", price: 299.99, quantity: 1 }]
167
- })
168
- );
130
+ const analytics = await createServerAnalytics({
131
+ providers: {
132
+ posthog: { apiKey: process.env.POSTHOG_API_KEY! },
133
+ },
134
+ });
169
135
 
170
- return Response.json({ success: true });
171
- }
136
+ await analytics.track("Order Completed", { orderId: "ord-123", total: 99.99 });
172
137
  ```
173
138
 
174
- #### E-commerce Events
139
+ ### Console + HTTP Only (no external deps needed)
175
140
 
176
141
  ```typescript
177
- import { ecommerce } from "@repo/analytics/client/next";
178
-
179
- // Product viewed
180
- ecommerce.PRODUCT_VIEWED({
181
- product_id: "prod_123",
182
- name: "Premium Plan",
183
- price: 299.99,
184
- currency: "USD"
185
- });
142
+ import { createClientAnalytics } from "@od-oneapp/analytics/client";
186
143
 
187
- // Product added to cart
188
- ecommerce.PRODUCT_ADDED({
189
- cart_id: "cart_abc",
190
- product_id: "prod_123",
191
- quantity: 1,
192
- price: 299.99
144
+ const analytics = await createClientAnalytics({
145
+ providers: {
146
+ console: { enabled: true },
147
+ http: { options: { endpoint: "/api/v1/ingest" } },
148
+ },
193
149
  });
194
150
 
195
- // Order completed
196
- ecommerce.ORDER_COMPLETED({
197
- order_id: "order_789",
198
- revenue: 499.97,
199
- currency: "USD",
200
- products: [
201
- /* ... */
202
- ],
203
- payment_method: "card"
204
- });
151
+ await analytics.track("Page Loaded", { path: window.location.pathname });
205
152
  ```
206
153
 
207
- #### AI Product Events
154
+ ### Event Catalogs (Zod-validated)
208
155
 
209
156
  ```typescript
210
- import { ai } from "@repo/analytics/client/next";
157
+ import { ecommerceCatalog, aiCatalog } from "@od-oneapp/analytics/catalogs";
211
158
 
212
- // Chat message sent
213
- ai.CHAT_MESSAGE_SENT({
214
- conversation_id: "conv_123",
215
- message_id: "msg_456",
216
- model_id: "gpt-4",
217
- message_length: 150
159
+ // Type-safe ecommerce events
160
+ const event = ecommerceCatalog.track("Product Viewed", {
161
+ product_id: "sku-123",
162
+ name: "Premium Plan",
163
+ price: 29.99,
164
+ currency: "USD",
218
165
  });
219
166
 
220
- // Message regenerated
221
- ai.MESSAGE_REGENERATED({
222
- conversation_id: "conv_123",
167
+ // Type-safe AI events
168
+ const aiEvent = aiCatalog.track("Chat Message Sent", {
169
+ conversation_id: "conv-123",
223
170
  model_id: "gpt-4",
224
- original_message_id: "msg_456",
225
- attempt_number: 2,
226
- reason: "user-requested"
227
- });
228
-
229
- // Conversation branched
230
- ai.CONVERSATION_BRANCHED({
231
- conversation_id: "conv_123",
232
- parent_conversation_id: "conv_122",
233
- branch_point_message_id: "msg_450",
234
- reason: "explore-alternative"
171
+ message_length: 150,
235
172
  });
236
173
  ```
237
174
 
@@ -239,39 +176,35 @@ ai.CONVERSATION_BRANCHED({
239
176
 
240
177
  ## Architecture
241
178
 
242
- ### Four-File Export Pattern
243
-
244
179
  ```
245
- @repo/analytics
246
- ├── /client → Browser-only (posthog-js, @vercel/analytics client)
247
- ├── /server → Node.js server (posthog-node, segment server)
248
- ├── /client/next → Next.js client (hooks, provider, components)
249
- ├── /server/next → Next.js server (API routes, server components)
250
- ├── /server/edge Edge runtime (middleware, edge API routes)
251
- └── /shared Environment-agnostic (emitters, types, utils)
180
+ @od-oneapp/analytics
181
+ ├── /client → Browser-only (built-in registry + dynamic external loader)
182
+ ├── /server → Node.js server (built-in registry + dynamic external loader)
183
+ ├── /client/next → Next.js client (hooks, provider, components, dynamic imports)
184
+ ├── /server/next → Next.js server (re-exports from /server)
185
+ ├── /types TypeScript types + MissingProviderPackageError
186
+ ├── /catalogs Zod-validated event catalogs
187
+ └── /providers/http → Built-in HTTP provider
252
188
  ```
253
189
 
254
190
  **Import Rules:**
255
191
 
256
- - Client components: `@repo/analytics/client/next`
257
- - Server components/API routes: `@repo/analytics/server/next`
258
- - Edge runtime: `@repo/analytics/server/edge`
259
- - Never mix: Client + server imports cause build errors
260
-
261
- **Edge Runtime Limitations:**
192
+ - Client components: `@od-oneapp/analytics/client/next`
193
+ - Server components/API routes: `@od-oneapp/analytics/server/next`
194
+ - Non-Next.js client: `@od-oneapp/analytics/client`
195
+ - Non-Next.js server: `@od-oneapp/analytics/server`
262
196
 
263
- The `/server/edge` export provides a simplified implementation compatible with edge runtime:
197
+ **Provider Architecture:**
264
198
 
265
- - Basic tracking (track, identify, page, group, alias)
266
- - ✅ Console provider (console API)
267
- - PostHog provider (HTTP API, no SDK dependency)
268
- - Emitter pattern support (`emit()`)
269
- - No event deduplication (no LRU cache)
270
- - No rate limiting enforcement
271
- - No feature flags (requires Node.js SDK)
272
- - ❌ No batch processing optimization
199
+ | Provider | Type | Package |
200
+ |----------|------|---------|
201
+ | Console | Built-in | (included) |
202
+ | HTTP | Built-in | (included) |
203
+ | PostHog | Opt-in | `@od-oneapp/integration-posthog` |
204
+ | Segment | Opt-in | `@od-oneapp/integration-segment` |
205
+ | Vercel | Opt-in | `@od-oneapp/integration-vercel` |
273
206
 
274
- For full features, use `/server` or `/server/next` in Node.js environments.
207
+ External providers are loaded dynamically at runtime via `import()` only when configured. If the package isn't installed, a `MissingProviderPackageError` is thrown with the install command.
275
208
 
276
209
  ---
277
210
 
@@ -280,230 +213,78 @@ For full features, use `/server` or `/server/next` in Node.js environments.
280
213
  ### Analytics Manager
281
214
 
282
215
  ```typescript
283
- // Create analytics instance
284
216
  const analytics = await createClientAnalytics(config);
285
217
 
286
- // Track events
287
218
  await analytics.track("Event Name", { property: "value" });
288
-
289
- // Identify users
290
219
  await analytics.identify("user_123", { email: "user@example.com" });
291
-
292
- // Track page views
293
220
  await analytics.page("/pricing", { title: "Pricing Page" });
294
-
295
- // Group/organization
296
221
  await analytics.group("org_456", { name: "Acme Corp" });
297
222
 
298
- // Emit emitter payloads
223
+ // Emitter pattern
299
224
  const event = track("Event", { data: "value" });
300
225
  await analytics.emit(event);
301
226
 
302
227
  // Batch processing
303
- await analytics.emitBatch([event1, event2, event3], {
304
- concurrency: 5,
305
- failFast: false
306
- });
228
+ await analytics.emitBatch([event1, event2, event3]);
307
229
  ```
308
230
 
309
231
  ### React Hooks
310
232
 
311
233
  ```typescript
312
- // Access analytics manager
313
234
  const analytics = useAnalytics();
235
+ const track = useTrackEvent();
236
+ const identify = useIdentifyUser();
314
237
 
315
- // Track on mount
316
- useTrackEvent("Page Viewed", { page: "/dashboard" });
317
-
318
- // Identify user on mount
319
- useIdentifyUser(user.id, { email: user.email });
320
-
321
- // Auto page tracking
322
- usePageTracking();
323
- ```
324
-
325
- ---
326
-
327
- ## Feature Flags (PostHog)
328
-
329
- ### Client-Side
330
-
331
- ```typescript
332
- import { useAnalytics } from '@repo/analytics/client/next';
333
-
334
- function FeatureFlag() {
335
- const analytics = useAnalytics();
336
- const provider = analytics.getProvider('posthog');
337
- const [enabled, setEnabled] = useState(false);
338
-
339
- useEffect(() => {
340
- provider?.isFeatureEnabled('new-feature').then(setEnabled);
341
- }, [provider]);
342
-
343
- return enabled ? <NewFeature /> : <OldFeature />;
344
- }
238
+ usePageTracking({ trackSearch: true });
345
239
  ```
346
240
 
347
- ### Server-Side
241
+ ### Tracked Components
348
242
 
349
243
  ```tsx
350
- // app/page.tsx
351
- import { createServerAnalytics } from "@repo/analytics/server/next";
244
+ <TrackedButton eventName="Sign Up Clicked" properties={{ location: "header" }}>
245
+ Sign Up
246
+ </TrackedButton>
352
247
 
353
- export default async function Page() {
354
- const analytics = await createServerAnalytics({
355
- providers: { posthog: { apiKey: process.env.POSTHOG_API_KEY! } }
356
- });
357
-
358
- const provider = analytics.getProvider("posthog");
359
- const showFeature = await provider?.getFeatureFlag("new-feature", "user_123");
360
-
361
- return <div>{showFeature ? <New /> : <Old />}</div>;
362
- }
363
- ```
364
-
365
- ---
366
-
367
- ## Troubleshooting
368
-
369
- ### Common Issues
370
-
371
- **"Analytics not initialized"**
372
-
373
- - Ensure you await `createClientAnalytics()` or `createServerAnalytics()`
374
-
375
- **"Provider not available in this environment"**
376
-
377
- - Check you're using correct import path (client vs server vs edge)
378
-
379
- **Events not showing in PostHog**
380
-
381
- - Verify API key is correct
382
- - Enable debug mode: `options: { debug: true }`
383
- - Check network tab for failed requests
384
-
385
- **"structuredClone is not defined"**
386
-
387
- - Upgrade to Node.js 22+ (required)
388
-
389
- ### Debug Mode
390
-
391
- ```typescript
392
- const analytics = await createClientAnalytics({
393
- providers: {
394
- posthog: {
395
- apiKey: "...",
396
- options: { debug: true }
397
- }
398
- },
399
- debug: true,
400
- onInfo: (msg) => console.log("[Analytics]", msg),
401
- onError: (err, ctx) => console.error("[Analytics Error]", err, ctx)
402
- });
248
+ <TrackedLink href="/products" eventName="Product Link Clicked">
249
+ View Products
250
+ </TrackedLink>
403
251
  ```
404
252
 
405
- ### Health Check
406
-
407
- ```typescript
408
- const health = await analytics.healthCheck(5000);
409
- console.log("Healthy:", health.healthy);
410
- console.log("Providers:", health.providers);
411
- ```
412
-
413
- ---
414
-
415
- ## Security
416
-
417
- ⚠️ **Important Security Notes:**
418
-
419
- 1. **Never track PII** - Avoid email, phone, SSN, credit cards
420
- 2. **Sanitize input** - Validate all properties before tracking
421
- 3. **Use env variables** - Never hardcode API keys
422
- 4. **Rotate keys** - Update API keys periodically
423
-
424
- **Security Features (Implemented):**
425
-
426
- - ✅ Input sanitization (`sanitizeProperties()`)
427
- - ✅ PII detection and redaction (`containsPII()`, `redactPII()`)
428
- - ✅ XSS protection (`stripHTML()`)
429
- - ✅ Payload size limits (default: 100KB max)
430
- - ✅ Dangerous key blocking (prevents `__proto__`, `constructor`)
431
- - ✅ Rate limiting (token bucket algorithm, 100 calls/second default)
432
-
433
- **Usage:**
253
+ ### Error Handling
434
254
 
435
255
  ```typescript
436
- import { sanitizeProperties, containsPII } from "@repo/analytics/server";
437
-
438
- // Sanitize before tracking
439
- const sanitized = sanitizeProperties(userInput, {
440
- stripPII: true,
441
- stripHTML: true,
442
- maxPayloadSize: 50_000 // 50KB
443
- });
256
+ import { MissingProviderPackageError } from "@od-oneapp/analytics/types";
444
257
 
445
- // Check for PII
446
- if (containsPII(JSON.stringify(properties))) {
447
- console.warn("PII detected in analytics payload");
258
+ try {
259
+ const analytics = await createClientAnalytics({
260
+ providers: { posthog: { apiKey: "..." } },
261
+ });
262
+ } catch (error) {
263
+ if (error instanceof MissingProviderPackageError) {
264
+ console.error(error.message);
265
+ // "Analytics provider "posthog" is configured but its package is not installed.
266
+ // Run: pnpm add @od-oneapp/integration-posthog"
267
+ }
448
268
  }
449
269
  ```
450
270
 
451
271
  ---
452
272
 
453
- ## Documentation
273
+ ## Security
454
274
 
455
- - **Full Documentation**: [Analytics Package Docs](../../apps/docs/packages/analytics.mdx)
456
- - **Audit Findings**: [AUDIT_FINDINGS.md](./AUDIT_FINDINGS.md)
457
- - **API Reference**: See source code JSDoc comments
458
- - **Examples**: [`src/examples/`](./src/examples/)
275
+ - Input sanitization (`sanitizeProperties()`)
276
+ - PII detection and redaction (`containsPII()`, `redactPII()`)
277
+ - XSS protection (`stripHTML()`)
278
+ - Payload size limits (default: 100KB max)
279
+ - Rate limiting (token bucket algorithm)
459
280
 
460
281
  ---
461
282
 
462
283
  ## Development
463
284
 
464
285
  ```bash
465
- # Install dependencies
466
- pnpm install
467
-
468
- # Run tests
469
- pnpm --filter=@repo/analytics test
470
-
471
- # Type check
472
- pnpm --filter=@repo/analytics typecheck
473
-
474
- # Lint
475
- pnpm --filter=@repo/analytics lint
476
-
477
- # Coverage
478
- pnpm --filter=@repo/analytics test:coverage
479
-
480
- # Check circular deps
481
- pnpm --filter=@repo/analytics circular
286
+ pnpm --filter @od-oneapp/analytics test
287
+ pnpm --filter @od-oneapp/analytics typecheck
288
+ pnpm --filter @od-oneapp/analytics lint
289
+ pnpm --filter @od-oneapp/analytics build
482
290
  ```
483
-
484
- ---
485
-
486
- ## Support
487
-
488
- - **Issues**: [GitHub Issues](https://github.com/your-org/monorepo/issues)
489
- - **Discussions**: [GitHub Discussions](https://github.com/your-org/monorepo/discussions)
490
-
491
- ---
492
-
493
- ## License
494
-
495
- MIT License
496
-
497
- ---
498
-
499
- **Built with ❤️ by the Platform Team**
500
-
501
- ## 📚 Comprehensive Documentation
502
-
503
- For detailed documentation, see:
504
-
505
- - **[Audit Reports](../../apps/docs/content/docs/audits/analytics/)** - Comprehensive audits, fixes, and security
506
- reviews
507
- - **[Technical Guides](../../apps/docs/content/docs/packages/analytics/)** - Implementation guides and best practices
508
-
509
- All comprehensive documentation has been centralized in the docs app.