@od-oneapp/analytics 2026.1.1301
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/README.md +509 -0
- package/dist/ai-YMnynb-t.mjs +3347 -0
- package/dist/ai-YMnynb-t.mjs.map +1 -0
- package/dist/chunk-DQk6qfdC.mjs +18 -0
- package/dist/client-CTzJVFU5.mjs +9 -0
- package/dist/client-CTzJVFU5.mjs.map +1 -0
- package/dist/client-CcFTauAh.mjs +54 -0
- package/dist/client-CcFTauAh.mjs.map +1 -0
- package/dist/client-CeOLjbac.mjs +281 -0
- package/dist/client-CeOLjbac.mjs.map +1 -0
- package/dist/client-D339NFJS.mjs +267 -0
- package/dist/client-D339NFJS.mjs.map +1 -0
- package/dist/client-next.d.mts +62 -0
- package/dist/client-next.d.mts.map +1 -0
- package/dist/client-next.mjs +525 -0
- package/dist/client-next.mjs.map +1 -0
- package/dist/client.d.mts +30 -0
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +186 -0
- package/dist/client.mjs.map +1 -0
- package/dist/config-DPS6bSYo.d.mts +34 -0
- package/dist/config-DPS6bSYo.d.mts.map +1 -0
- package/dist/config-P6P5adJg.mjs +287 -0
- package/dist/config-P6P5adJg.mjs.map +1 -0
- package/dist/console-8bND3mMU.mjs +128 -0
- package/dist/console-8bND3mMU.mjs.map +1 -0
- package/dist/ecommerce-Cgu4wlux.mjs +993 -0
- package/dist/ecommerce-Cgu4wlux.mjs.map +1 -0
- package/dist/emitters-6-nKo8i-.mjs +208 -0
- package/dist/emitters-6-nKo8i-.mjs.map +1 -0
- package/dist/emitters-DldkVSPp.d.mts +12 -0
- package/dist/emitters-DldkVSPp.d.mts.map +1 -0
- package/dist/index-BfNWgfa5.d.mts +1494 -0
- package/dist/index-BfNWgfa5.d.mts.map +1 -0
- package/dist/index-BkIWe--N.d.mts +953 -0
- package/dist/index-BkIWe--N.d.mts.map +1 -0
- package/dist/index-jPzXRn52.d.mts +184 -0
- package/dist/index-jPzXRn52.d.mts.map +1 -0
- package/dist/manager-DvRRjza6.d.mts +76 -0
- package/dist/manager-DvRRjza6.d.mts.map +1 -0
- package/dist/posthog-bootstrap-CYfIy_WS.mjs +1769 -0
- package/dist/posthog-bootstrap-CYfIy_WS.mjs.map +1 -0
- package/dist/posthog-bootstrap-DWxFrxlt.d.mts +81 -0
- package/dist/posthog-bootstrap-DWxFrxlt.d.mts.map +1 -0
- package/dist/providers-http-client.d.mts +37 -0
- package/dist/providers-http-client.d.mts.map +1 -0
- package/dist/providers-http-client.mjs +320 -0
- package/dist/providers-http-client.mjs.map +1 -0
- package/dist/providers-http-server.d.mts +31 -0
- package/dist/providers-http-server.d.mts.map +1 -0
- package/dist/providers-http-server.mjs +297 -0
- package/dist/providers-http-server.mjs.map +1 -0
- package/dist/providers-http.d.mts +46 -0
- package/dist/providers-http.d.mts.map +1 -0
- package/dist/providers-http.mjs +4 -0
- package/dist/server-edge.d.mts +9 -0
- package/dist/server-edge.d.mts.map +1 -0
- package/dist/server-edge.mjs +373 -0
- package/dist/server-edge.mjs.map +1 -0
- package/dist/server-next.d.mts +67 -0
- package/dist/server-next.d.mts.map +1 -0
- package/dist/server-next.mjs +193 -0
- package/dist/server-next.mjs.map +1 -0
- package/dist/server.d.mts +10 -0
- package/dist/server.mjs +7 -0
- package/dist/service-cYtBBL8x.mjs +945 -0
- package/dist/service-cYtBBL8x.mjs.map +1 -0
- package/dist/shared.d.mts +16 -0
- package/dist/shared.d.mts.map +1 -0
- package/dist/shared.mjs +93 -0
- package/dist/shared.mjs.map +1 -0
- package/dist/types-BxBnNQ0V.d.mts +354 -0
- package/dist/types-BxBnNQ0V.d.mts.map +1 -0
- package/dist/types-CBvxUEaF.d.mts +216 -0
- package/dist/types-CBvxUEaF.d.mts.map +1 -0
- package/dist/types.d.mts +4 -0
- package/dist/types.mjs +0 -0
- package/dist/vercel-types-lwakUfoI.d.mts +102 -0
- package/dist/vercel-types-lwakUfoI.d.mts.map +1 -0
- package/package.json +129 -0
- package/src/client/index.ts +164 -0
- package/src/client/manager.ts +71 -0
- package/src/client/next/components.tsx +270 -0
- package/src/client/next/hooks.ts +217 -0
- package/src/client/next/manager.ts +141 -0
- package/src/client/next.ts +144 -0
- package/src/client-next.ts +101 -0
- package/src/client.ts +89 -0
- package/src/examples/ai-sdk-patterns.ts +583 -0
- package/src/examples/emitter-patterns.ts +476 -0
- package/src/examples/nextjs-emitter-patterns.tsx +403 -0
- package/src/next/app-router.tsx +564 -0
- package/src/next/client.ts +419 -0
- package/src/next/index.ts +84 -0
- package/src/next/middleware.ts +429 -0
- package/src/next/rsc.tsx +300 -0
- package/src/next/server.ts +253 -0
- package/src/next/types.d.ts +220 -0
- package/src/providers/base-provider.ts +419 -0
- package/src/providers/console/client.ts +10 -0
- package/src/providers/console/index.ts +152 -0
- package/src/providers/console/server.ts +6 -0
- package/src/providers/console/types.ts +15 -0
- package/src/providers/http/client.ts +464 -0
- package/src/providers/http/index.ts +30 -0
- package/src/providers/http/server.ts +396 -0
- package/src/providers/http/types.ts +135 -0
- package/src/providers/posthog/client.ts +518 -0
- package/src/providers/posthog/index.ts +11 -0
- package/src/providers/posthog/server.ts +329 -0
- package/src/providers/posthog/types.ts +104 -0
- package/src/providers/segment/client.ts +113 -0
- package/src/providers/segment/index.ts +11 -0
- package/src/providers/segment/server.ts +115 -0
- package/src/providers/segment/types.ts +51 -0
- package/src/providers/vercel/client.ts +102 -0
- package/src/providers/vercel/index.ts +11 -0
- package/src/providers/vercel/server.ts +89 -0
- package/src/providers/vercel/types.ts +27 -0
- package/src/server/index.ts +103 -0
- package/src/server/manager.ts +62 -0
- package/src/server/next.ts +210 -0
- package/src/server-edge.ts +442 -0
- package/src/server-next.ts +39 -0
- package/src/server.ts +106 -0
- package/src/shared/emitters/ai/README.md +981 -0
- package/src/shared/emitters/ai/events/agent.ts +130 -0
- package/src/shared/emitters/ai/events/artifacts.ts +167 -0
- package/src/shared/emitters/ai/events/chat.ts +126 -0
- package/src/shared/emitters/ai/events/chatbot-ecommerce.ts +133 -0
- package/src/shared/emitters/ai/events/completion.ts +103 -0
- package/src/shared/emitters/ai/events/content-generation.ts +347 -0
- package/src/shared/emitters/ai/events/conversation.ts +332 -0
- package/src/shared/emitters/ai/events/product-features.ts +1402 -0
- package/src/shared/emitters/ai/events/streaming.ts +114 -0
- package/src/shared/emitters/ai/events/tool.ts +93 -0
- package/src/shared/emitters/ai/index.ts +69 -0
- package/src/shared/emitters/ai/track-ai-sdk.ts +74 -0
- package/src/shared/emitters/ai/track-ai.ts +50 -0
- package/src/shared/emitters/ai/types.ts +1041 -0
- package/src/shared/emitters/ai/utils.ts +468 -0
- package/src/shared/emitters/ecommerce/events/cart-checkout.ts +106 -0
- package/src/shared/emitters/ecommerce/events/coupon.ts +49 -0
- package/src/shared/emitters/ecommerce/events/engagement.ts +61 -0
- package/src/shared/emitters/ecommerce/events/marketplace.ts +119 -0
- package/src/shared/emitters/ecommerce/events/order.ts +199 -0
- package/src/shared/emitters/ecommerce/events/product.ts +205 -0
- package/src/shared/emitters/ecommerce/events/registry.ts +123 -0
- package/src/shared/emitters/ecommerce/events/wishlist-sharing.ts +140 -0
- package/src/shared/emitters/ecommerce/index.ts +46 -0
- package/src/shared/emitters/ecommerce/track-ecommerce.ts +53 -0
- package/src/shared/emitters/ecommerce/types.ts +314 -0
- package/src/shared/emitters/ecommerce/utils.ts +216 -0
- package/src/shared/emitters/emitter-types.ts +974 -0
- package/src/shared/emitters/emitters.ts +292 -0
- package/src/shared/emitters/helpers.ts +419 -0
- package/src/shared/emitters/index.ts +66 -0
- package/src/shared/index.ts +142 -0
- package/src/shared/ingestion/index.ts +66 -0
- package/src/shared/ingestion/schemas.ts +386 -0
- package/src/shared/ingestion/service.ts +628 -0
- package/src/shared/node22-features.ts +848 -0
- package/src/shared/providers/console-provider.ts +160 -0
- package/src/shared/types/base-types.ts +54 -0
- package/src/shared/types/console-types.ts +19 -0
- package/src/shared/types/posthog-types.ts +131 -0
- package/src/shared/types/segment-types.ts +15 -0
- package/src/shared/types/types.ts +397 -0
- package/src/shared/types/vercel-types.ts +19 -0
- package/src/shared/utils/config-client.ts +19 -0
- package/src/shared/utils/config.ts +250 -0
- package/src/shared/utils/emitter-adapter.ts +212 -0
- package/src/shared/utils/manager.test.ts +36 -0
- package/src/shared/utils/manager.ts +1322 -0
- package/src/shared/utils/posthog-bootstrap.ts +136 -0
- package/src/shared/utils/posthog-client-utils.ts +48 -0
- package/src/shared/utils/posthog-next-utils.ts +282 -0
- package/src/shared/utils/posthog-server-utils.ts +210 -0
- package/src/shared/utils/rate-limit.ts +289 -0
- package/src/shared/utils/security.ts +545 -0
- package/src/shared/utils/validation-client.ts +161 -0
- package/src/shared/utils/validation.ts +399 -0
- package/src/shared.ts +155 -0
- package/src/types/index.ts +62 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Analytics Emitters - The Recommended Way to Track Events
|
|
3
|
+
*
|
|
4
|
+
* Emitters provide type-safe, consistent event tracking following
|
|
5
|
+
* the Segment.io specification. They are the primary pattern for
|
|
6
|
+
* analytics in this package.
|
|
7
|
+
*
|
|
8
|
+
* **Core Emitters**:
|
|
9
|
+
* - `identify()`: Identify users with traits
|
|
10
|
+
* - `track()`: Track custom events
|
|
11
|
+
* - `page()`: Track page views
|
|
12
|
+
* - `screen()`: Track screen views (mobile)
|
|
13
|
+
* - `group()`: Associate users with groups
|
|
14
|
+
* - `alias()`: Alias user IDs
|
|
15
|
+
*
|
|
16
|
+
* **Namespace Emitters**:
|
|
17
|
+
* - `ecommerce.*`: E-commerce specific events (product viewed, cart updated, etc.)
|
|
18
|
+
* - `aiSdk.*`: AI SDK v6 specific events (chat completion, tool calls, etc.)
|
|
19
|
+
*
|
|
20
|
+
* **Helper Utilities**:
|
|
21
|
+
* - `ContextBuilder`: Build consistent context across events
|
|
22
|
+
* - `PayloadBuilder`: Chain emitter creation
|
|
23
|
+
* - `EventBatch`: Batch related events with shared context
|
|
24
|
+
* - `createUserSession()`: Create a user session tracking flow
|
|
25
|
+
* - `createAnonymousSession()`: Create an anonymous user tracking flow
|
|
26
|
+
* - `withMetadata()`: Add consistent metadata to events
|
|
27
|
+
* - `withUTM()`: Add UTM parameters to events
|
|
28
|
+
*
|
|
29
|
+
* @module @od-oneapp/analytics/shared/emitters
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
// Export core emitter functions as the primary API
|
|
33
|
+
export {
|
|
34
|
+
alias,
|
|
35
|
+
group,
|
|
36
|
+
identify,
|
|
37
|
+
page,
|
|
38
|
+
screen,
|
|
39
|
+
// Main emitter functions
|
|
40
|
+
track,
|
|
41
|
+
} from './emitters';
|
|
42
|
+
|
|
43
|
+
// Export all emitter types
|
|
44
|
+
export * from './emitter-types';
|
|
45
|
+
|
|
46
|
+
// Export helper utilities for easier emitter usage
|
|
47
|
+
export * from './helpers';
|
|
48
|
+
|
|
49
|
+
// Export convenience builders
|
|
50
|
+
export {
|
|
51
|
+
ContextBuilder,
|
|
52
|
+
EventBatch,
|
|
53
|
+
PayloadBuilder,
|
|
54
|
+
createAnonymousSession,
|
|
55
|
+
createUserSession,
|
|
56
|
+
withMetadata,
|
|
57
|
+
withUTM,
|
|
58
|
+
} from './helpers';
|
|
59
|
+
|
|
60
|
+
// Export ecommerce emitters as a namespace
|
|
61
|
+
export * as ecommerce from './ecommerce';
|
|
62
|
+
|
|
63
|
+
// Export AI SDK v6 emitters as a namespace
|
|
64
|
+
export * as aiSdk from './ai';
|
|
65
|
+
|
|
66
|
+
// Re-export ecommerce types for convenience
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared Analytics Exports
|
|
3
|
+
*
|
|
4
|
+
* This module provides shared exports for both client and server environments.
|
|
5
|
+
* Contains types, utilities, and emitters that work universally across all
|
|
6
|
+
* runtime environments (Node.js, Edge, Browser).
|
|
7
|
+
*
|
|
8
|
+
* @module @od-oneapp/analytics/shared
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Export all types
|
|
12
|
+
export type {
|
|
13
|
+
AnalyticsConfig,
|
|
14
|
+
AnalyticsContext,
|
|
15
|
+
// Core types
|
|
16
|
+
AnalyticsProvider,
|
|
17
|
+
ProviderConfig,
|
|
18
|
+
ProviderFactory,
|
|
19
|
+
ProviderRegistry,
|
|
20
|
+
TrackingOptions,
|
|
21
|
+
} from './types/types';
|
|
22
|
+
|
|
23
|
+
// Export provider-specific types
|
|
24
|
+
export type {
|
|
25
|
+
// Segment types
|
|
26
|
+
SegmentConfig,
|
|
27
|
+
SegmentOptions,
|
|
28
|
+
} from './types/segment-types';
|
|
29
|
+
|
|
30
|
+
export type {
|
|
31
|
+
BootstrapData,
|
|
32
|
+
EnhancedPostHogProvider,
|
|
33
|
+
ExperimentInfo,
|
|
34
|
+
// PostHog types
|
|
35
|
+
PostHogConfig,
|
|
36
|
+
PostHogCookie,
|
|
37
|
+
PostHogOptions,
|
|
38
|
+
} from './types/posthog-types';
|
|
39
|
+
|
|
40
|
+
export type {
|
|
41
|
+
// Vercel types
|
|
42
|
+
VercelConfig,
|
|
43
|
+
VercelOptions,
|
|
44
|
+
} from './types/vercel-types';
|
|
45
|
+
|
|
46
|
+
export type {
|
|
47
|
+
// Console types
|
|
48
|
+
ConsoleConfig,
|
|
49
|
+
ConsoleOptions,
|
|
50
|
+
LogLevel,
|
|
51
|
+
} from './types/console-types';
|
|
52
|
+
|
|
53
|
+
// Export emitter types
|
|
54
|
+
export type {
|
|
55
|
+
AnalyticsEmitter,
|
|
56
|
+
EmitterAliasPayload,
|
|
57
|
+
EmitterBasePayload,
|
|
58
|
+
EmitterConfig,
|
|
59
|
+
EmitterContext,
|
|
60
|
+
EmitterEventProperties,
|
|
61
|
+
EmitterGroupPayload,
|
|
62
|
+
EmitterGroupTraits,
|
|
63
|
+
EmitterIdentifyPayload,
|
|
64
|
+
EmitterIntegrations,
|
|
65
|
+
EmitterOptions,
|
|
66
|
+
EmitterPagePayload,
|
|
67
|
+
EmitterPayload,
|
|
68
|
+
EmitterScreenPayload,
|
|
69
|
+
EmitterTrackPayload,
|
|
70
|
+
EmitterUserTraits,
|
|
71
|
+
} from './emitters/emitter-types';
|
|
72
|
+
|
|
73
|
+
// Export all emitters
|
|
74
|
+
export * from './emitters';
|
|
75
|
+
|
|
76
|
+
// Export utilities
|
|
77
|
+
export {
|
|
78
|
+
PROVIDER_REQUIREMENTS,
|
|
79
|
+
createConfigBuilder,
|
|
80
|
+
// Configuration
|
|
81
|
+
getAnalyticsConfig,
|
|
82
|
+
validateConfig,
|
|
83
|
+
} from './utils/config';
|
|
84
|
+
|
|
85
|
+
export type { ConfigBuilder, ConfigRequirements } from './utils/config';
|
|
86
|
+
|
|
87
|
+
// Export Node 22+ enhanced features
|
|
88
|
+
export {
|
|
89
|
+
AdvancedEventBatcher,
|
|
90
|
+
Node22AnalyticsManager,
|
|
91
|
+
createNode22AnalyticsManager,
|
|
92
|
+
node22Analytics,
|
|
93
|
+
} from './node22-features';
|
|
94
|
+
|
|
95
|
+
export {
|
|
96
|
+
debugConfig,
|
|
97
|
+
// Validation
|
|
98
|
+
validateAnalyticsConfig,
|
|
99
|
+
validateConfigOrThrow,
|
|
100
|
+
validateProvider,
|
|
101
|
+
} from './utils/validation';
|
|
102
|
+
|
|
103
|
+
export type { ValidationError, ValidationResult } from './utils/validation';
|
|
104
|
+
|
|
105
|
+
export {
|
|
106
|
+
// Manager
|
|
107
|
+
createAnalyticsManager,
|
|
108
|
+
} from './utils/manager';
|
|
109
|
+
|
|
110
|
+
export { AnalyticsManager as AnalyticsManagerClass } from './utils/manager';
|
|
111
|
+
|
|
112
|
+
export {
|
|
113
|
+
createBootstrapData,
|
|
114
|
+
createMinimalBootstrapData,
|
|
115
|
+
// PostHog utilities
|
|
116
|
+
generateDistinctId,
|
|
117
|
+
getCachedBootstrapData,
|
|
118
|
+
getDistinctIdFromCookies,
|
|
119
|
+
setCachedBootstrapData,
|
|
120
|
+
} from './utils/posthog-bootstrap';
|
|
121
|
+
|
|
122
|
+
export {
|
|
123
|
+
createPostHogConfig,
|
|
124
|
+
// PostHog Next.js utilities
|
|
125
|
+
createPostHogServerClient,
|
|
126
|
+
getCompleteBootstrapData,
|
|
127
|
+
} from './utils/posthog-next-utils';
|
|
128
|
+
|
|
129
|
+
export {
|
|
130
|
+
createEmitterProcessor,
|
|
131
|
+
processAliasPayload,
|
|
132
|
+
// Emitter adapter utilities
|
|
133
|
+
processEmitterPayload,
|
|
134
|
+
processGroupPayload,
|
|
135
|
+
processIdentifyPayload,
|
|
136
|
+
processPagePayload,
|
|
137
|
+
processTrackPayload,
|
|
138
|
+
trackEcommerceEvent,
|
|
139
|
+
} from './utils/emitter-adapter';
|
|
140
|
+
|
|
141
|
+
// Export console provider (works in both environments)
|
|
142
|
+
export { ConsoleProvider } from './providers/console-provider';
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Event Ingestion Module
|
|
3
|
+
*
|
|
4
|
+
* Exports for the event ingestion system. Provides schemas, service, and utilities
|
|
5
|
+
* for validating and processing analytics events from external sources.
|
|
6
|
+
*
|
|
7
|
+
* @module @od-oneapp/analytics/shared/ingestion
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Export schemas
|
|
11
|
+
export {
|
|
12
|
+
// Base schemas
|
|
13
|
+
PropertyValueSchema,
|
|
14
|
+
PropertyObjectSchema,
|
|
15
|
+
EmitterContextSchema,
|
|
16
|
+
|
|
17
|
+
// Event type schemas
|
|
18
|
+
TrackEventSchema,
|
|
19
|
+
IdentifyEventSchema,
|
|
20
|
+
PageEventSchema,
|
|
21
|
+
ScreenEventSchema,
|
|
22
|
+
GroupEventSchema,
|
|
23
|
+
AliasEventSchema,
|
|
24
|
+
EventPayloadSchema,
|
|
25
|
+
|
|
26
|
+
// Request/response schemas
|
|
27
|
+
SingleEventRequestSchema,
|
|
28
|
+
BatchEventRequestSchema,
|
|
29
|
+
IngestionRequestSchema,
|
|
30
|
+
EventResultSchema,
|
|
31
|
+
IngestionSuccessResponseSchema,
|
|
32
|
+
IngestionErrorResponseSchema,
|
|
33
|
+
IngestionResponseSchema,
|
|
34
|
+
} from './schemas';
|
|
35
|
+
|
|
36
|
+
// Export types
|
|
37
|
+
export type {
|
|
38
|
+
PropertyValue,
|
|
39
|
+
PropertyObject,
|
|
40
|
+
EmitterContext,
|
|
41
|
+
TrackEvent,
|
|
42
|
+
IdentifyEvent,
|
|
43
|
+
PageEvent,
|
|
44
|
+
ScreenEvent,
|
|
45
|
+
GroupEvent,
|
|
46
|
+
AliasEvent,
|
|
47
|
+
EventPayload,
|
|
48
|
+
SingleEventRequest,
|
|
49
|
+
BatchEventRequest,
|
|
50
|
+
IngestionRequest,
|
|
51
|
+
EventResult,
|
|
52
|
+
IngestionSuccessResponse,
|
|
53
|
+
IngestionErrorResponse,
|
|
54
|
+
IngestionResponse,
|
|
55
|
+
} from './schemas';
|
|
56
|
+
|
|
57
|
+
// Export service
|
|
58
|
+
export {
|
|
59
|
+
IngestionService,
|
|
60
|
+
createIngestionService,
|
|
61
|
+
validateEventPayload,
|
|
62
|
+
validateBatchPayload,
|
|
63
|
+
} from './service';
|
|
64
|
+
|
|
65
|
+
// Export service types
|
|
66
|
+
export type { IngestionContext, IngestionServiceConfig, IngestionMetrics } from './service';
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Event Ingestion Schemas and Validation
|
|
3
|
+
*
|
|
4
|
+
* Defines Zod schemas for validating event ingestion payloads. These schemas
|
|
5
|
+
* ensure type-safe, secure event ingestion with proper validation.
|
|
6
|
+
*
|
|
7
|
+
* **Key Features**:
|
|
8
|
+
* - CloudEvents-style fields for future interoperability
|
|
9
|
+
* - Support for single events and batched arrays
|
|
10
|
+
* - Strict validation of required fields
|
|
11
|
+
* - Typed extensions per event category
|
|
12
|
+
*
|
|
13
|
+
* @module @od-oneapp/analytics/shared/ingestion/schemas
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
|
|
18
|
+
// =============================================================================
|
|
19
|
+
// Base Schemas
|
|
20
|
+
// =============================================================================
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Property value schema - safe, serializable values only.
|
|
24
|
+
*/
|
|
25
|
+
export const PropertyValueSchema = z.union([
|
|
26
|
+
z.string(),
|
|
27
|
+
z.number(),
|
|
28
|
+
z.boolean(),
|
|
29
|
+
z.null(),
|
|
30
|
+
z.date(), // Accept Date objects only; ISO strings are already handled as strings
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Property object schema with nested structure support.
|
|
35
|
+
*/
|
|
36
|
+
export const PropertyObjectSchema: z.ZodType<Record<string, unknown>> = z.record(
|
|
37
|
+
z.string(),
|
|
38
|
+
z.lazy(() =>
|
|
39
|
+
z.union([PropertyValueSchema, z.array(PropertyValueSchema), z.record(z.string(), z.unknown())]),
|
|
40
|
+
),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Emitter context schema - contextual information about the environment.
|
|
45
|
+
*/
|
|
46
|
+
export const EmitterContextSchema = z
|
|
47
|
+
.object({
|
|
48
|
+
/** Application information */
|
|
49
|
+
app: z
|
|
50
|
+
.object({
|
|
51
|
+
name: z.string().optional(),
|
|
52
|
+
version: z.string().optional(),
|
|
53
|
+
build: z.string().optional(),
|
|
54
|
+
namespace: z.string().optional(),
|
|
55
|
+
})
|
|
56
|
+
.optional(),
|
|
57
|
+
|
|
58
|
+
/** Campaign/UTM information */
|
|
59
|
+
campaign: z
|
|
60
|
+
.object({
|
|
61
|
+
name: z.string().optional(),
|
|
62
|
+
source: z.string().optional(),
|
|
63
|
+
medium: z.string().optional(),
|
|
64
|
+
term: z.string().optional(),
|
|
65
|
+
content: z.string().optional(),
|
|
66
|
+
})
|
|
67
|
+
.passthrough()
|
|
68
|
+
.optional(),
|
|
69
|
+
|
|
70
|
+
/** Device information */
|
|
71
|
+
device: z
|
|
72
|
+
.object({
|
|
73
|
+
id: z.string().optional(),
|
|
74
|
+
manufacturer: z.string().optional(),
|
|
75
|
+
model: z.string().optional(),
|
|
76
|
+
name: z.string().optional(),
|
|
77
|
+
type: z.string().optional(),
|
|
78
|
+
version: z.string().optional(),
|
|
79
|
+
})
|
|
80
|
+
.optional(),
|
|
81
|
+
|
|
82
|
+
/** User's IP address */
|
|
83
|
+
ip: z.string().optional(),
|
|
84
|
+
|
|
85
|
+
/** Library making the request */
|
|
86
|
+
library: z
|
|
87
|
+
.object({
|
|
88
|
+
name: z.string(),
|
|
89
|
+
version: z.string(),
|
|
90
|
+
})
|
|
91
|
+
.optional(),
|
|
92
|
+
|
|
93
|
+
/** User's locale (e.g., 'en-US') */
|
|
94
|
+
locale: z.string().optional(),
|
|
95
|
+
|
|
96
|
+
/** Network information */
|
|
97
|
+
network: z
|
|
98
|
+
.object({
|
|
99
|
+
bluetooth: z.boolean().optional(),
|
|
100
|
+
carrier: z.string().optional(),
|
|
101
|
+
cellular: z.boolean().optional(),
|
|
102
|
+
wifi: z.boolean().optional(),
|
|
103
|
+
})
|
|
104
|
+
.optional(),
|
|
105
|
+
|
|
106
|
+
/** OS information */
|
|
107
|
+
os: z
|
|
108
|
+
.object({
|
|
109
|
+
name: z.string().optional(),
|
|
110
|
+
version: z.string().optional(),
|
|
111
|
+
})
|
|
112
|
+
.optional(),
|
|
113
|
+
|
|
114
|
+
/** Page information */
|
|
115
|
+
page: z
|
|
116
|
+
.object({
|
|
117
|
+
path: z.string().optional(),
|
|
118
|
+
// Use permissive string validation for referrer/url since real-world values
|
|
119
|
+
// may be malformed, truncated, or non-standard (e.g., data: URIs, about:blank)
|
|
120
|
+
referrer: z.string().optional(),
|
|
121
|
+
search: z.string().optional(),
|
|
122
|
+
title: z.string().optional(),
|
|
123
|
+
url: z.string().optional(),
|
|
124
|
+
})
|
|
125
|
+
.optional(),
|
|
126
|
+
|
|
127
|
+
/** Screen information */
|
|
128
|
+
screen: z
|
|
129
|
+
.object({
|
|
130
|
+
density: z.number().optional(),
|
|
131
|
+
height: z.number().int().positive().optional(),
|
|
132
|
+
width: z.number().int().positive().optional(),
|
|
133
|
+
})
|
|
134
|
+
.optional(),
|
|
135
|
+
|
|
136
|
+
/** User's timezone (tzdata string) */
|
|
137
|
+
timezone: z.string().optional(),
|
|
138
|
+
|
|
139
|
+
/** Group/account ID */
|
|
140
|
+
groupId: z.string().optional(),
|
|
141
|
+
|
|
142
|
+
/** User agent string */
|
|
143
|
+
userAgent: z.string().optional(),
|
|
144
|
+
|
|
145
|
+
/** Channel where request originated */
|
|
146
|
+
channel: z.enum(['server', 'browser', 'mobile', 'api']).optional(),
|
|
147
|
+
|
|
148
|
+
/** Location context */
|
|
149
|
+
location: z
|
|
150
|
+
.object({
|
|
151
|
+
city: z.string().optional(),
|
|
152
|
+
country: z.string().optional(),
|
|
153
|
+
latitude: z.number().optional(),
|
|
154
|
+
longitude: z.number().optional(),
|
|
155
|
+
region: z.string().optional(),
|
|
156
|
+
})
|
|
157
|
+
.optional(),
|
|
158
|
+
})
|
|
159
|
+
.passthrough();
|
|
160
|
+
|
|
161
|
+
// =============================================================================
|
|
162
|
+
// Event Type Schemas
|
|
163
|
+
// =============================================================================
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Base payload schema - common fields for all event types.
|
|
167
|
+
*/
|
|
168
|
+
const BasePayloadSchema = z
|
|
169
|
+
.object({
|
|
170
|
+
/** Anonymous ID if user is not identified */
|
|
171
|
+
anonymousId: z.string().max(255).optional(),
|
|
172
|
+
|
|
173
|
+
/** User ID (at least one of userId or anonymousId required) */
|
|
174
|
+
userId: z.string().max(255).optional(),
|
|
175
|
+
|
|
176
|
+
/** Timestamp when the event occurred */
|
|
177
|
+
timestamp: z.union([z.string().datetime(), z.date()]).optional(),
|
|
178
|
+
|
|
179
|
+
/** Original timestamp before processing */
|
|
180
|
+
originalTimestamp: z.union([z.string().datetime(), z.date()]).optional(),
|
|
181
|
+
|
|
182
|
+
/** Context and control fields */
|
|
183
|
+
context: EmitterContextSchema.optional(),
|
|
184
|
+
|
|
185
|
+
/** Message ID for deduplication */
|
|
186
|
+
messageId: z.string().uuid().optional(),
|
|
187
|
+
})
|
|
188
|
+
.refine(data => Boolean(data.anonymousId) || Boolean(data.userId), {
|
|
189
|
+
message: 'Either anonymousId or userId must be provided',
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Track event payload schema.
|
|
194
|
+
* Uses safeExtend() because BasePayloadSchema has refinements (Zod v4 requirement).
|
|
195
|
+
*/
|
|
196
|
+
export const TrackEventSchema = BasePayloadSchema.safeExtend({
|
|
197
|
+
type: z.literal('track'),
|
|
198
|
+
event: z.string().min(1).max(255),
|
|
199
|
+
properties: PropertyObjectSchema.optional(),
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Identify event payload schema.
|
|
204
|
+
* Uses safeExtend() because BasePayloadSchema has refinements (Zod v4 requirement).
|
|
205
|
+
*/
|
|
206
|
+
export const IdentifyEventSchema = BasePayloadSchema.safeExtend({
|
|
207
|
+
type: z.literal('identify'),
|
|
208
|
+
userId: z.string().min(1).max(255),
|
|
209
|
+
traits: PropertyObjectSchema.optional(),
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Page event payload schema.
|
|
214
|
+
* Uses safeExtend() because BasePayloadSchema has refinements (Zod v4 requirement).
|
|
215
|
+
*/
|
|
216
|
+
export const PageEventSchema = BasePayloadSchema.safeExtend({
|
|
217
|
+
type: z.literal('page'),
|
|
218
|
+
name: z.string().max(255).optional(),
|
|
219
|
+
category: z.string().max(255).optional(),
|
|
220
|
+
properties: PropertyObjectSchema.optional(),
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Screen event payload schema.
|
|
225
|
+
* Uses safeExtend() because BasePayloadSchema has refinements (Zod v4 requirement).
|
|
226
|
+
*/
|
|
227
|
+
export const ScreenEventSchema = BasePayloadSchema.safeExtend({
|
|
228
|
+
type: z.literal('screen'),
|
|
229
|
+
name: z.string().max(255).optional(),
|
|
230
|
+
category: z.string().max(255).optional(),
|
|
231
|
+
properties: PropertyObjectSchema.optional(),
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Group event payload schema.
|
|
236
|
+
* Uses safeExtend() because BasePayloadSchema has refinements (Zod v4 requirement).
|
|
237
|
+
*/
|
|
238
|
+
export const GroupEventSchema = BasePayloadSchema.safeExtend({
|
|
239
|
+
type: z.literal('group'),
|
|
240
|
+
groupId: z.string().min(1).max(255),
|
|
241
|
+
traits: PropertyObjectSchema.optional(),
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Alias event payload schema.
|
|
246
|
+
* Uses safeExtend() because BasePayloadSchema has refinements (Zod v4 requirement).
|
|
247
|
+
*/
|
|
248
|
+
export const AliasEventSchema = BasePayloadSchema.safeExtend({
|
|
249
|
+
type: z.literal('alias'),
|
|
250
|
+
userId: z.string().min(1).max(255),
|
|
251
|
+
previousId: z.string().min(1).max(255),
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Union of all event payload schemas.
|
|
256
|
+
*/
|
|
257
|
+
export const EventPayloadSchema = z.discriminatedUnion('type', [
|
|
258
|
+
TrackEventSchema,
|
|
259
|
+
IdentifyEventSchema,
|
|
260
|
+
PageEventSchema,
|
|
261
|
+
ScreenEventSchema,
|
|
262
|
+
GroupEventSchema,
|
|
263
|
+
AliasEventSchema,
|
|
264
|
+
]);
|
|
265
|
+
|
|
266
|
+
// =============================================================================
|
|
267
|
+
// Ingestion Request Schemas
|
|
268
|
+
// =============================================================================
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Single event ingestion request schema.
|
|
272
|
+
*/
|
|
273
|
+
export const SingleEventRequestSchema = EventPayloadSchema;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Batch event ingestion request schema.
|
|
277
|
+
*
|
|
278
|
+
* The batch size limit is enforced at the service level via `maxBatchSize` config
|
|
279
|
+
* (default: 100) rather than in the schema, allowing for flexible configuration.
|
|
280
|
+
*/
|
|
281
|
+
export const BatchEventRequestSchema = z.object({
|
|
282
|
+
batch: z.array(EventPayloadSchema).min(1),
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Combined ingestion request schema - accepts single event or batch.
|
|
287
|
+
*/
|
|
288
|
+
export const IngestionRequestSchema = z.union([BatchEventRequestSchema, SingleEventRequestSchema]);
|
|
289
|
+
|
|
290
|
+
// =============================================================================
|
|
291
|
+
// Ingestion Response Schemas
|
|
292
|
+
// =============================================================================
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Event processing result.
|
|
296
|
+
*/
|
|
297
|
+
export const EventResultSchema = z.object({
|
|
298
|
+
/** Server-generated event ID */
|
|
299
|
+
id: z.string().uuid(),
|
|
300
|
+
|
|
301
|
+
/** Original message ID if provided */
|
|
302
|
+
messageId: z.string().uuid().optional(),
|
|
303
|
+
|
|
304
|
+
/** Event type */
|
|
305
|
+
type: z.enum(['track', 'identify', 'page', 'screen', 'group', 'alias']),
|
|
306
|
+
|
|
307
|
+
/** Processing status */
|
|
308
|
+
status: z.enum(['accepted', 'rejected']),
|
|
309
|
+
|
|
310
|
+
/** Error message if rejected */
|
|
311
|
+
error: z.string().optional(),
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Successful ingestion response schema.
|
|
316
|
+
*/
|
|
317
|
+
export const IngestionSuccessResponseSchema = z.object({
|
|
318
|
+
/** Whether the request was successful */
|
|
319
|
+
success: z.literal(true),
|
|
320
|
+
|
|
321
|
+
/** Number of events accepted */
|
|
322
|
+
accepted: z.number().int().nonnegative(),
|
|
323
|
+
|
|
324
|
+
/** Number of events rejected */
|
|
325
|
+
rejected: z.number().int().nonnegative(),
|
|
326
|
+
|
|
327
|
+
/** Per-event results */
|
|
328
|
+
results: z.array(EventResultSchema),
|
|
329
|
+
|
|
330
|
+
/** Server timestamp when events were received */
|
|
331
|
+
receivedAt: z.string().datetime(),
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Error response schema.
|
|
336
|
+
*/
|
|
337
|
+
export const IngestionErrorResponseSchema = z.object({
|
|
338
|
+
/** Whether the request was successful */
|
|
339
|
+
success: z.literal(false),
|
|
340
|
+
|
|
341
|
+
/** Error code */
|
|
342
|
+
code: z.string(),
|
|
343
|
+
|
|
344
|
+
/** Error message */
|
|
345
|
+
error: z.string(),
|
|
346
|
+
|
|
347
|
+
/** Field-level validation errors */
|
|
348
|
+
fieldErrors: z
|
|
349
|
+
.array(
|
|
350
|
+
z.object({
|
|
351
|
+
path: z.array(z.union([z.string(), z.number()])),
|
|
352
|
+
message: z.string(),
|
|
353
|
+
}),
|
|
354
|
+
)
|
|
355
|
+
.optional(),
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Combined response schema.
|
|
360
|
+
*/
|
|
361
|
+
export const IngestionResponseSchema = z.union([
|
|
362
|
+
IngestionSuccessResponseSchema,
|
|
363
|
+
IngestionErrorResponseSchema,
|
|
364
|
+
]);
|
|
365
|
+
|
|
366
|
+
// =============================================================================
|
|
367
|
+
// Type Exports
|
|
368
|
+
// =============================================================================
|
|
369
|
+
|
|
370
|
+
export type PropertyValue = z.infer<typeof PropertyValueSchema>;
|
|
371
|
+
export type PropertyObject = z.infer<typeof PropertyObjectSchema>;
|
|
372
|
+
export type EmitterContext = z.infer<typeof EmitterContextSchema>;
|
|
373
|
+
export type TrackEvent = z.infer<typeof TrackEventSchema>;
|
|
374
|
+
export type IdentifyEvent = z.infer<typeof IdentifyEventSchema>;
|
|
375
|
+
export type PageEvent = z.infer<typeof PageEventSchema>;
|
|
376
|
+
export type ScreenEvent = z.infer<typeof ScreenEventSchema>;
|
|
377
|
+
export type GroupEvent = z.infer<typeof GroupEventSchema>;
|
|
378
|
+
export type AliasEvent = z.infer<typeof AliasEventSchema>;
|
|
379
|
+
export type EventPayload = z.infer<typeof EventPayloadSchema>;
|
|
380
|
+
export type SingleEventRequest = z.infer<typeof SingleEventRequestSchema>;
|
|
381
|
+
export type BatchEventRequest = z.infer<typeof BatchEventRequestSchema>;
|
|
382
|
+
export type IngestionRequest = z.infer<typeof IngestionRequestSchema>;
|
|
383
|
+
export type EventResult = z.infer<typeof EventResultSchema>;
|
|
384
|
+
export type IngestionSuccessResponse = z.infer<typeof IngestionSuccessResponseSchema>;
|
|
385
|
+
export type IngestionErrorResponse = z.infer<typeof IngestionErrorResponseSchema>;
|
|
386
|
+
export type IngestionResponse = z.infer<typeof IngestionResponseSchema>;
|