@codaco/analytics 8.0.0 → 9.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/CHANGELOG.md +12 -0
- package/MIGRATION.md +404 -0
- package/README.md +486 -4
- package/dist/chunk-3NEQVIC4.js +72 -0
- package/dist/chunk-3NEQVIC4.js.map +1 -0
- package/dist/index.d.ts +113 -82
- package/dist/index.js +188 -160
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +44 -0
- package/dist/server.js +153 -0
- package/dist/server.js.map +1 -0
- package/dist/types-Ymgjicqi.d.ts +145 -0
- package/package.json +27 -7
- package/src/__tests__/client.test.ts +276 -0
- package/src/__tests__/index.test.ts +207 -0
- package/src/__tests__/utils.test.ts +105 -0
- package/src/client.ts +151 -0
- package/src/config.ts +92 -0
- package/src/hooks.ts +79 -0
- package/src/index.ts +69 -237
- package/src/provider.tsx +60 -0
- package/src/server.ts +213 -0
- package/src/types.ts +183 -0
- package/src/utils.ts +1 -0
- package/tsconfig.json +1 -1
- package/vitest.config.ts +18 -0
package/README.md
CHANGED
|
@@ -1,9 +1,491 @@
|
|
|
1
1
|
# @codaco/analytics
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
PostHog analytics wrapper for Network Canvas applications with installation ID tracking, error reporting, and feature flags support.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
This package provides a simplified abstraction over PostHog analytics, designed specifically for Network Canvas applications. It ensures that every analytics event includes an installation ID, making it possible to track deployments without compromising user privacy.
|
|
8
8
|
|
|
9
|
-
**
|
|
9
|
+
**Important:** This package is designed to work exclusively with the Cloudflare Worker reverse proxy at `ph-relay.networkcanvas.com`. All PostHog authentication is handled by the worker, so you don't need to configure API keys in your application.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Installation ID Tracking**: Automatically includes installation ID with every event
|
|
14
|
+
- **Error Tracking**: Capture errors with full stack traces
|
|
15
|
+
- **Feature Flags**: Built-in support for PostHog feature flags and A/B testing
|
|
16
|
+
- **Non-blocking API**: All tracking calls are fire-and-forget
|
|
17
|
+
- **Type Safety**: Full TypeScript support with Zod schemas
|
|
18
|
+
- **Server & Client**: Works in React components, server actions, and API routes
|
|
19
|
+
- **Privacy-First**: Analytics can be completely disabled via environment variable
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm add @codaco/analytics
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
**Minimal environment variables!** Only `DISABLE_ANALYTICS` is supported for disabling tracking. All other configuration is passed directly to the analytics provider.
|
|
30
|
+
|
|
31
|
+
### Environment Variables (Optional)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Optional: Disable all analytics tracking
|
|
35
|
+
DISABLE_ANALYTICS=true
|
|
36
|
+
# or for Next.js client-side
|
|
37
|
+
NEXT_PUBLIC_DISABLE_ANALYTICS=true
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Client-Side Usage (React)
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
// In your root layout (app/layout.tsx)
|
|
44
|
+
import { AnalyticsProvider } from '@codaco/analytics';
|
|
45
|
+
|
|
46
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
47
|
+
return (
|
|
48
|
+
<html>
|
|
49
|
+
<body>
|
|
50
|
+
<AnalyticsProvider
|
|
51
|
+
config={{
|
|
52
|
+
installationId: 'your-unique-installation-id',
|
|
53
|
+
}}
|
|
54
|
+
>
|
|
55
|
+
{children}
|
|
56
|
+
</AnalyticsProvider>
|
|
57
|
+
</body>
|
|
58
|
+
</html>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
// In your components
|
|
65
|
+
import { useAnalytics } from '@codaco/analytics';
|
|
66
|
+
|
|
67
|
+
export function MyComponent() {
|
|
68
|
+
const { trackEvent, trackError } = useAnalytics();
|
|
69
|
+
|
|
70
|
+
const handleSetup = () => {
|
|
71
|
+
trackEvent('app_setup', {
|
|
72
|
+
metadata: { version: '1.0.0' }
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const handleError = (error: Error) => {
|
|
77
|
+
trackError(error, {
|
|
78
|
+
metadata: { context: 'component-mount' }
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
return <button onClick={handleSetup}>Setup App</button>;
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Server-Side Usage
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
// First, initialize in your root layout or middleware
|
|
90
|
+
import { initServerAnalytics } from '@codaco/analytics/server';
|
|
91
|
+
|
|
92
|
+
initServerAnalytics({
|
|
93
|
+
installationId: 'your-unique-installation-id',
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Then use in API routes or server actions
|
|
97
|
+
import { serverAnalytics } from '@codaco/analytics/server';
|
|
98
|
+
|
|
99
|
+
export async function POST(request: Request) {
|
|
100
|
+
try {
|
|
101
|
+
// Your logic here
|
|
102
|
+
|
|
103
|
+
serverAnalytics.trackEvent('data_exported', {
|
|
104
|
+
metadata: { format: 'csv', rowCount: 100 }
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
return Response.json({ success: true });
|
|
108
|
+
} catch (error) {
|
|
109
|
+
serverAnalytics.trackError(error as Error);
|
|
110
|
+
return Response.json({ error: 'Failed' }, { status: 500 });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## API Reference
|
|
116
|
+
|
|
117
|
+
### Event Types
|
|
118
|
+
|
|
119
|
+
The package supports the following standard event types:
|
|
120
|
+
|
|
121
|
+
- `app_setup` - Initial application setup
|
|
122
|
+
- `protocol_installed` - Protocol installation
|
|
123
|
+
- `interview_started` - Interview start
|
|
124
|
+
- `interview_completed` - Interview completion
|
|
125
|
+
- `data_exported` - Data export
|
|
126
|
+
- `error` - Error events (use `trackError()` instead)
|
|
127
|
+
|
|
128
|
+
You can also send custom events with any string name.
|
|
129
|
+
|
|
130
|
+
### Client-Side API
|
|
131
|
+
|
|
132
|
+
#### `AnalyticsProvider`
|
|
133
|
+
|
|
134
|
+
Wraps your application to provide analytics context.
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
<AnalyticsProvider config={config}>
|
|
138
|
+
{children}
|
|
139
|
+
</AnalyticsProvider>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Config Options:**
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
interface AnalyticsConfig {
|
|
146
|
+
// Required: Unique identifier for this installation
|
|
147
|
+
installationId: string;
|
|
148
|
+
|
|
149
|
+
// Optional: PostHog API key
|
|
150
|
+
// Defaults to a placeholder (authentication handled by the proxy)
|
|
151
|
+
apiKey?: string;
|
|
152
|
+
|
|
153
|
+
// Optional: PostHog API host
|
|
154
|
+
// Hardcoded to "https://ph-relay.networkcanvas.com" by default
|
|
155
|
+
// Only override if using a different proxy endpoint
|
|
156
|
+
apiHost?: string;
|
|
157
|
+
|
|
158
|
+
// Optional: Disable all tracking
|
|
159
|
+
disabled?: boolean;
|
|
160
|
+
|
|
161
|
+
// Optional: Enable debug mode
|
|
162
|
+
debug?: boolean;
|
|
163
|
+
|
|
164
|
+
// Optional: PostHog-specific options
|
|
165
|
+
posthogOptions?: {
|
|
166
|
+
disable_session_recording?: boolean;
|
|
167
|
+
autocapture?: boolean;
|
|
168
|
+
capture_pageview?: boolean;
|
|
169
|
+
// ... other PostHog options
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### `useAnalytics()`
|
|
175
|
+
|
|
176
|
+
React hook to access analytics in components.
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
const analytics = useAnalytics();
|
|
180
|
+
|
|
181
|
+
// Track an event
|
|
182
|
+
analytics.trackEvent('protocol_installed', {
|
|
183
|
+
metadata: { protocolId: '123', version: '2.0' }
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// Track an error
|
|
187
|
+
analytics.trackError(error, {
|
|
188
|
+
metadata: { context: 'import' }
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Feature flags
|
|
192
|
+
const isEnabled = analytics.isFeatureEnabled('new-feature');
|
|
193
|
+
const variant = analytics.getFeatureFlag('experiment');
|
|
194
|
+
const allFlags = analytics.getFeatureFlags();
|
|
195
|
+
analytics.reloadFeatureFlags();
|
|
196
|
+
|
|
197
|
+
// User identification (optional, for advanced use cases)
|
|
198
|
+
analytics.identify('user-123', { email: 'user@example.com' });
|
|
199
|
+
analytics.reset();
|
|
200
|
+
|
|
201
|
+
// Utilities
|
|
202
|
+
analytics.isEnabled(); // Check if analytics is enabled
|
|
203
|
+
analytics.getInstallationId(); // Get the installation ID
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### `useFeatureFlag(flagKey: string)`
|
|
207
|
+
|
|
208
|
+
React hook for feature flags (returns boolean).
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
const isNewUIEnabled = useFeatureFlag('new-ui');
|
|
212
|
+
|
|
213
|
+
if (isNewUIEnabled) {
|
|
214
|
+
return <NewUI />;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return <OldUI />;
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### `useFeatureFlagValue(flagKey: string)`
|
|
221
|
+
|
|
222
|
+
React hook for multivariate feature flags.
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
const theme = useFeatureFlagValue('theme-experiment');
|
|
226
|
+
|
|
227
|
+
return <div className={theme === 'dark' ? 'dark' : 'light'}>
|
|
228
|
+
Content
|
|
229
|
+
</div>;
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Server-Side API
|
|
233
|
+
|
|
234
|
+
#### `serverAnalytics`
|
|
235
|
+
|
|
236
|
+
Pre-configured server-side analytics instance (auto-initializes from env vars).
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
import { serverAnalytics } from '@codaco/analytics/server';
|
|
240
|
+
|
|
241
|
+
serverAnalytics.trackEvent('interview_completed', {
|
|
242
|
+
metadata: { duration: 300, completionRate: 0.95 }
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
serverAnalytics.trackError(error);
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### `initServerAnalytics(config)`
|
|
249
|
+
|
|
250
|
+
Initialize server analytics (required before using serverAnalytics).
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
import { initServerAnalytics, getServerAnalytics } from '@codaco/analytics/server';
|
|
254
|
+
|
|
255
|
+
// In your app startup (e.g., root layout)
|
|
256
|
+
initServerAnalytics({
|
|
257
|
+
installationId: 'your-unique-installation-id',
|
|
258
|
+
// Optional overrides:
|
|
259
|
+
// disabled: false,
|
|
260
|
+
// debug: true,
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Later, in your code
|
|
264
|
+
const analytics = getServerAnalytics();
|
|
265
|
+
analytics.trackEvent('app_setup');
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Note:** Feature flags are **not supported** in server-side mode. Use client-side hooks for feature flags.
|
|
269
|
+
|
|
270
|
+
## Configuration
|
|
271
|
+
|
|
272
|
+
### Default Settings
|
|
273
|
+
|
|
274
|
+
The package comes with sensible defaults (no environment variables needed):
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
{
|
|
278
|
+
apiHost: "https://ph-relay.networkcanvas.com", // Hardcoded
|
|
279
|
+
apiKey: "phc_proxy_mode_placeholder", // Placeholder for proxy mode
|
|
280
|
+
disabled: false,
|
|
281
|
+
debug: false,
|
|
282
|
+
posthogOptions: {
|
|
283
|
+
disable_session_recording: true,
|
|
284
|
+
autocapture: false,
|
|
285
|
+
capture_pageview: false,
|
|
286
|
+
capture_pageleave: false,
|
|
287
|
+
cross_subdomain_cookie: false,
|
|
288
|
+
advanced_disable_feature_flags: false,
|
|
289
|
+
persistence: "localStorage+cookie",
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Configuration
|
|
295
|
+
|
|
296
|
+
All configuration is passed directly via the `config` prop.
|
|
297
|
+
|
|
298
|
+
**Environment Variables:**
|
|
299
|
+
- `DISABLE_ANALYTICS` or `NEXT_PUBLIC_DISABLE_ANALYTICS` - Set to `"true"` to disable all tracking
|
|
300
|
+
|
|
301
|
+
No other environment variables are used (API host and key are hardcoded for proxy mode).
|
|
302
|
+
|
|
303
|
+
### Disabling Analytics
|
|
304
|
+
|
|
305
|
+
Analytics can be disabled in two ways:
|
|
306
|
+
|
|
307
|
+
**1. Via environment variable (recommended for development/testing):**
|
|
308
|
+
```bash
|
|
309
|
+
DISABLE_ANALYTICS=true
|
|
310
|
+
# or for Next.js client-side
|
|
311
|
+
NEXT_PUBLIC_DISABLE_ANALYTICS=true
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**2. Via config prop:**
|
|
315
|
+
```tsx
|
|
316
|
+
<AnalyticsProvider config={{
|
|
317
|
+
installationId: 'your-id',
|
|
318
|
+
disabled: true
|
|
319
|
+
}}>
|
|
320
|
+
{children}
|
|
321
|
+
</AnalyticsProvider>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
When disabled (by either method), all analytics methods become no-ops (no tracking occurs).
|
|
325
|
+
|
|
326
|
+
## Feature Flags & A/B Testing
|
|
327
|
+
|
|
328
|
+
PostHog feature flags allow you to:
|
|
329
|
+
|
|
330
|
+
- Toggle features on/off remotely
|
|
331
|
+
- Run A/B tests
|
|
332
|
+
- Gradual rollouts
|
|
333
|
+
- User targeting
|
|
334
|
+
|
|
335
|
+
### Setting Up Feature Flags
|
|
336
|
+
|
|
337
|
+
1. Create a feature flag in your PostHog dashboard
|
|
338
|
+
2. Use the hooks or API in your code:
|
|
339
|
+
|
|
340
|
+
```tsx
|
|
341
|
+
function ExperimentComponent() {
|
|
342
|
+
const variant = useFeatureFlagValue('checkout-flow');
|
|
343
|
+
|
|
344
|
+
switch (variant) {
|
|
345
|
+
case 'variant-a':
|
|
346
|
+
return <CheckoutFlowA />;
|
|
347
|
+
case 'variant-b':
|
|
348
|
+
return <CheckoutFlowB />;
|
|
349
|
+
default:
|
|
350
|
+
return <CheckoutFlowDefault />;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
## Error Tracking
|
|
356
|
+
|
|
357
|
+
Errors are automatically enriched with:
|
|
358
|
+
|
|
359
|
+
- Error message
|
|
360
|
+
- Error name
|
|
361
|
+
- Full stack trace
|
|
362
|
+
- Cause (if available)
|
|
363
|
+
- Any additional metadata you provide
|
|
364
|
+
|
|
365
|
+
```tsx
|
|
366
|
+
try {
|
|
367
|
+
// Your code
|
|
368
|
+
} catch (error) {
|
|
369
|
+
trackError(error as Error, {
|
|
370
|
+
metadata: {
|
|
371
|
+
context: 'data-import',
|
|
372
|
+
fileName: 'protocol.json',
|
|
373
|
+
attemptNumber: 3,
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
## Migration from Old Analytics
|
|
380
|
+
|
|
381
|
+
See [MIGRATION.md](./MIGRATION.md) for a complete migration guide from the old analytics system.
|
|
382
|
+
|
|
383
|
+
Quick summary of changes:
|
|
384
|
+
|
|
385
|
+
- **Event names**: Now use `snake_case` instead of `PascalCase`
|
|
386
|
+
- `AppSetup` → `app_setup`
|
|
387
|
+
- `ProtocolInstalled` → `protocol_installed`
|
|
388
|
+
- **API**: `makeEventTracker()` → `useAnalytics()` hook
|
|
389
|
+
- **Route handler**: No longer needed (PostHog handles everything)
|
|
390
|
+
- **Installation ID**: Now set via config instead of route handler
|
|
391
|
+
|
|
392
|
+
## Architecture
|
|
393
|
+
|
|
394
|
+
This package uses a reverse proxy architecture for security and reliability:
|
|
395
|
+
|
|
396
|
+
```
|
|
397
|
+
┌─────────────────────┐
|
|
398
|
+
│ React App │
|
|
399
|
+
│ (Client) │
|
|
400
|
+
│ │
|
|
401
|
+
│ useAnalytics() │
|
|
402
|
+
│ ↓ │
|
|
403
|
+
│ PostHog JS SDK │
|
|
404
|
+
│ (no API key) │
|
|
405
|
+
└──────────┬──────────┘
|
|
406
|
+
│
|
|
407
|
+
│ HTTPS
|
|
408
|
+
↓
|
|
409
|
+
┌─────────────────────┐
|
|
410
|
+
│ Cloudflare Worker │
|
|
411
|
+
│ (Reverse Proxy) │
|
|
412
|
+
│ ph-relay.network │
|
|
413
|
+
│ canvas.com │
|
|
414
|
+
│ │
|
|
415
|
+
│ • Injects API key │
|
|
416
|
+
│ • Adds CORS │
|
|
417
|
+
│ • Bypasses blockers│
|
|
418
|
+
└──────────┬──────────┘
|
|
419
|
+
│
|
|
420
|
+
│ HTTPS + Auth
|
|
421
|
+
↓
|
|
422
|
+
┌─────────────────────┐
|
|
423
|
+
│ PostHog Cloud │
|
|
424
|
+
│ (US Region) │
|
|
425
|
+
│ │
|
|
426
|
+
│ Analytics Dashboard│
|
|
427
|
+
│ Feature Flags │
|
|
428
|
+
│ A/B Testing │
|
|
429
|
+
└─────────────────────┘
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Benefits:**
|
|
433
|
+
- API key stays secure (server-side only)
|
|
434
|
+
- Avoids ad-blockers
|
|
435
|
+
- Uses your own domain
|
|
436
|
+
- Centralized authentication
|
|
437
|
+
|
|
438
|
+
## Best Practices
|
|
439
|
+
|
|
440
|
+
1. **Always include metadata**: Helps with debugging and analysis
|
|
441
|
+
```ts
|
|
442
|
+
trackEvent('data_exported', {
|
|
443
|
+
metadata: { format: 'csv', size: 1024, duration: 230 }
|
|
444
|
+
});
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
2. **Use typed event names**: Import event types for autocomplete
|
|
448
|
+
```ts
|
|
449
|
+
import type { EventType } from '@codaco/analytics';
|
|
450
|
+
const event: EventType = 'app_setup';
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
3. **Don't block on analytics**: All calls are non-blocking by design
|
|
454
|
+
|
|
455
|
+
4. **Test with analytics disabled**: Set `NEXT_PUBLIC_DISABLE_ANALYTICS=true`
|
|
456
|
+
|
|
457
|
+
5. **Use feature flags for gradual rollouts**: Test features with a small percentage of users first
|
|
458
|
+
|
|
459
|
+
## Troubleshooting
|
|
460
|
+
|
|
461
|
+
### Events not appearing in PostHog
|
|
462
|
+
|
|
463
|
+
1. Verify the reverse proxy is running at `ph-relay.networkcanvas.com`
|
|
464
|
+
2. Check that the Cloudflare Worker has the `POSTHOG_API_KEY` environment variable set
|
|
465
|
+
3. Enable debug mode: `debug: true` in config
|
|
466
|
+
4. Check browser console for errors
|
|
467
|
+
5. Verify PostHog dashboard shows your project
|
|
468
|
+
6. Test the proxy endpoint directly: `curl https://ph-relay.networkcanvas.com`
|
|
469
|
+
|
|
470
|
+
### Feature flags not working
|
|
471
|
+
|
|
472
|
+
1. Ensure flags are created in PostHog dashboard
|
|
473
|
+
2. Check flag is enabled and has a rollout percentage
|
|
474
|
+
3. Reload flags: `analytics.reloadFeatureFlags()`
|
|
475
|
+
4. Feature flags only work client-side, not in server components
|
|
476
|
+
|
|
477
|
+
### TypeScript errors
|
|
478
|
+
|
|
479
|
+
1. Ensure `@types/react` is installed
|
|
480
|
+
2. Check TypeScript version is compatible (>= 5.0)
|
|
481
|
+
3. Rebuild the package: `pnpm build`
|
|
482
|
+
|
|
483
|
+
## License
|
|
484
|
+
|
|
485
|
+
MIT
|
|
486
|
+
|
|
487
|
+
## Support
|
|
488
|
+
|
|
489
|
+
For issues and questions:
|
|
490
|
+
- GitHub Issues: https://github.com/complexdatacollective/network-canvas-monorepo/issues
|
|
491
|
+
- Email: hello@complexdatacollective.org
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
var POSTHOG_PROXY_HOST = "https://ph-relay.networkcanvas.com";
|
|
3
|
+
var PROXY_MODE_DUMMY_KEY = "phc_proxy_mode_placeholder";
|
|
4
|
+
function isDisabledByEnv() {
|
|
5
|
+
if (typeof process === "undefined") {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
return process.env.DISABLE_ANALYTICS === "true" || process.env.NEXT_PUBLIC_DISABLE_ANALYTICS === "true";
|
|
9
|
+
}
|
|
10
|
+
var defaultConfig = {
|
|
11
|
+
// Always use the Cloudflare Worker reverse proxy
|
|
12
|
+
apiHost: POSTHOG_PROXY_HOST,
|
|
13
|
+
// Analytics enabled by default (can be disabled via env var or config option)
|
|
14
|
+
disabled: false,
|
|
15
|
+
// Debug mode disabled by default
|
|
16
|
+
debug: false,
|
|
17
|
+
// Default PostHog options
|
|
18
|
+
posthogOptions: {
|
|
19
|
+
// Disable session recording by default (can be enabled per-app)
|
|
20
|
+
disable_session_recording: true,
|
|
21
|
+
// Disable autocapture to keep events clean and intentional
|
|
22
|
+
autocapture: false,
|
|
23
|
+
// Disable automatic pageview capture (apps can enable if needed)
|
|
24
|
+
capture_pageview: false,
|
|
25
|
+
// Disable pageleave events
|
|
26
|
+
capture_pageleave: false,
|
|
27
|
+
// Don't use cross-subdomain cookies
|
|
28
|
+
cross_subdomain_cookie: false,
|
|
29
|
+
// Enable feature flags by default
|
|
30
|
+
advanced_disable_feature_flags: false,
|
|
31
|
+
// Send feature flag events
|
|
32
|
+
advanced_disable_feature_flags_on_first_load: false,
|
|
33
|
+
// Enable persistence for feature flags
|
|
34
|
+
persistence: "localStorage+cookie"
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
function mergeConfig(userConfig) {
|
|
38
|
+
return {
|
|
39
|
+
apiHost: userConfig.apiHost ?? defaultConfig.apiHost ?? POSTHOG_PROXY_HOST,
|
|
40
|
+
apiKey: userConfig.apiKey ?? PROXY_MODE_DUMMY_KEY,
|
|
41
|
+
installationId: userConfig.installationId,
|
|
42
|
+
disabled: userConfig.disabled ?? isDisabledByEnv() ?? defaultConfig.disabled ?? false,
|
|
43
|
+
debug: userConfig.debug ?? defaultConfig.debug ?? false,
|
|
44
|
+
posthogOptions: {
|
|
45
|
+
...defaultConfig.posthogOptions,
|
|
46
|
+
...userConfig.posthogOptions
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/utils.ts
|
|
52
|
+
function ensureError(value) {
|
|
53
|
+
if (!value) return new Error("No value was thrown");
|
|
54
|
+
if (value instanceof Error) return value;
|
|
55
|
+
if (Object.prototype.isPrototypeOf.call(value, Error)) return value;
|
|
56
|
+
let stringified = "[Unable to stringify the thrown value]";
|
|
57
|
+
try {
|
|
58
|
+
stringified = JSON.stringify(value);
|
|
59
|
+
} catch (e) {
|
|
60
|
+
console.error(e);
|
|
61
|
+
}
|
|
62
|
+
const error = new Error(`This value was thrown as is, not through an Error: ${stringified}`);
|
|
63
|
+
return error;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export {
|
|
67
|
+
isDisabledByEnv,
|
|
68
|
+
defaultConfig,
|
|
69
|
+
mergeConfig,
|
|
70
|
+
ensureError
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=chunk-3NEQVIC4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/utils.ts"],"sourcesContent":["import type { AnalyticsConfig } from \"./types\";\n\n/**\n * Hardcoded PostHog API host - always uses the Cloudflare Worker reverse proxy\n * Authentication is handled by the worker at this endpoint\n */\nconst POSTHOG_PROXY_HOST = \"https://ph-relay.networkcanvas.com\";\n\n/**\n * Dummy API key used for proxy mode\n * PostHog JS library requires an API key for initialization, but when using\n * the reverse proxy, authentication is handled by the Cloudflare Worker.\n * This placeholder key is used for client-side initialization only.\n */\nconst PROXY_MODE_DUMMY_KEY = \"phc_proxy_mode_placeholder\";\n\n/**\n * Check if analytics is disabled via environment variables\n */\nexport function isDisabledByEnv(): boolean {\n\tif (typeof process === \"undefined\") {\n\t\treturn false;\n\t}\n\n\treturn process.env.DISABLE_ANALYTICS === \"true\" || process.env.NEXT_PUBLIC_DISABLE_ANALYTICS === \"true\";\n}\n\n/**\n * Default configuration for analytics\n * API host and key are hardcoded, but disabled flag can be set via environment variables\n */\nexport const defaultConfig: Partial<AnalyticsConfig> = {\n\t// Always use the Cloudflare Worker reverse proxy\n\tapiHost: POSTHOG_PROXY_HOST,\n\n\t// Analytics enabled by default (can be disabled via env var or config option)\n\tdisabled: false,\n\n\t// Debug mode disabled by default\n\tdebug: false,\n\n\t// Default PostHog options\n\tposthogOptions: {\n\t\t// Disable session recording by default (can be enabled per-app)\n\t\tdisable_session_recording: true,\n\n\t\t// Disable autocapture to keep events clean and intentional\n\t\tautocapture: false,\n\n\t\t// Disable automatic pageview capture (apps can enable if needed)\n\t\tcapture_pageview: false,\n\n\t\t// Disable pageleave events\n\t\tcapture_pageleave: false,\n\n\t\t// Don't use cross-subdomain cookies\n\t\tcross_subdomain_cookie: false,\n\n\t\t// Enable feature flags by default\n\t\tadvanced_disable_feature_flags: false,\n\n\t\t// Send feature flag events\n\t\tadvanced_disable_feature_flags_on_first_load: false,\n\n\t\t// Enable persistence for feature flags\n\t\tpersistence: \"localStorage+cookie\",\n\t},\n};\n\n/**\n * Merge user config with defaults\n *\n * Note: This package is designed to work exclusively with the Cloudflare Worker\n * reverse proxy (ph-relay.networkcanvas.com). Authentication is handled by the\n * worker, so the API key is optional and defaults to a placeholder value.\n *\n * The only environment variable checked is DISABLE_ANALYTICS / NEXT_PUBLIC_DISABLE_ANALYTICS\n * for disabling tracking. All other configuration is hardcoded or passed explicitly.\n */\nexport function mergeConfig(userConfig: AnalyticsConfig): Required<AnalyticsConfig> {\n\treturn {\n\t\tapiHost: userConfig.apiHost ?? defaultConfig.apiHost ?? POSTHOG_PROXY_HOST,\n\t\tapiKey: userConfig.apiKey ?? PROXY_MODE_DUMMY_KEY,\n\t\tinstallationId: userConfig.installationId,\n\t\tdisabled: userConfig.disabled ?? isDisabledByEnv() ?? defaultConfig.disabled ?? false,\n\t\tdebug: userConfig.debug ?? defaultConfig.debug ?? false,\n\t\tposthogOptions: {\n\t\t\t...defaultConfig.posthogOptions,\n\t\t\t...userConfig.posthogOptions,\n\t\t},\n\t};\n}\n","// Helper function that ensures that a value is an Error\nexport function ensureError(value: unknown): Error {\n\tif (!value) return new Error(\"No value was thrown\");\n\n\tif (value instanceof Error) return value;\n\n\t// Test if value inherits from Error\n\tif (Object.prototype.isPrototypeOf.call(value, Error)) return value as Error & typeof value;\n\n\tlet stringified = \"[Unable to stringify the thrown value]\";\n\ttry {\n\t\tstringified = JSON.stringify(value);\n\t} catch (e) {\n\t\t// biome-ignore lint/suspicious/noConsole: logging\n\t\tconsole.error(e);\n\t}\n\n\tconst error = new Error(`This value was thrown as is, not through an Error: ${stringified}`);\n\treturn error;\n}\n"],"mappings":";AAMA,IAAM,qBAAqB;AAQ3B,IAAM,uBAAuB;AAKtB,SAAS,kBAA2B;AAC1C,MAAI,OAAO,YAAY,aAAa;AACnC,WAAO;AAAA,EACR;AAEA,SAAO,QAAQ,IAAI,sBAAsB,UAAU,QAAQ,IAAI,kCAAkC;AAClG;AAMO,IAAM,gBAA0C;AAAA;AAAA,EAEtD,SAAS;AAAA;AAAA,EAGT,UAAU;AAAA;AAAA,EAGV,OAAO;AAAA;AAAA,EAGP,gBAAgB;AAAA;AAAA,IAEf,2BAA2B;AAAA;AAAA,IAG3B,aAAa;AAAA;AAAA,IAGb,kBAAkB;AAAA;AAAA,IAGlB,mBAAmB;AAAA;AAAA,IAGnB,wBAAwB;AAAA;AAAA,IAGxB,gCAAgC;AAAA;AAAA,IAGhC,8CAA8C;AAAA;AAAA,IAG9C,aAAa;AAAA,EACd;AACD;AAYO,SAAS,YAAY,YAAwD;AACnF,SAAO;AAAA,IACN,SAAS,WAAW,WAAW,cAAc,WAAW;AAAA,IACxD,QAAQ,WAAW,UAAU;AAAA,IAC7B,gBAAgB,WAAW;AAAA,IAC3B,UAAU,WAAW,YAAY,gBAAgB,KAAK,cAAc,YAAY;AAAA,IAChF,OAAO,WAAW,SAAS,cAAc,SAAS;AAAA,IAClD,gBAAgB;AAAA,MACf,GAAG,cAAc;AAAA,MACjB,GAAG,WAAW;AAAA,IACf;AAAA,EACD;AACD;;;AC1FO,SAAS,YAAY,OAAuB;AAClD,MAAI,CAAC,MAAO,QAAO,IAAI,MAAM,qBAAqB;AAElD,MAAI,iBAAiB,MAAO,QAAO;AAGnC,MAAI,OAAO,UAAU,cAAc,KAAK,OAAO,KAAK,EAAG,QAAO;AAE9D,MAAI,cAAc;AAClB,MAAI;AACH,kBAAc,KAAK,UAAU,KAAK;AAAA,EACnC,SAAS,GAAG;AAEX,YAAQ,MAAM,CAAC;AAAA,EAChB;AAEA,QAAM,QAAQ,IAAI,MAAM,sDAAsD,WAAW,EAAE;AAC3F,SAAO;AACR;","names":[]}
|