@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.
Files changed (184) hide show
  1. package/README.md +509 -0
  2. package/dist/ai-YMnynb-t.mjs +3347 -0
  3. package/dist/ai-YMnynb-t.mjs.map +1 -0
  4. package/dist/chunk-DQk6qfdC.mjs +18 -0
  5. package/dist/client-CTzJVFU5.mjs +9 -0
  6. package/dist/client-CTzJVFU5.mjs.map +1 -0
  7. package/dist/client-CcFTauAh.mjs +54 -0
  8. package/dist/client-CcFTauAh.mjs.map +1 -0
  9. package/dist/client-CeOLjbac.mjs +281 -0
  10. package/dist/client-CeOLjbac.mjs.map +1 -0
  11. package/dist/client-D339NFJS.mjs +267 -0
  12. package/dist/client-D339NFJS.mjs.map +1 -0
  13. package/dist/client-next.d.mts +62 -0
  14. package/dist/client-next.d.mts.map +1 -0
  15. package/dist/client-next.mjs +525 -0
  16. package/dist/client-next.mjs.map +1 -0
  17. package/dist/client.d.mts +30 -0
  18. package/dist/client.d.mts.map +1 -0
  19. package/dist/client.mjs +186 -0
  20. package/dist/client.mjs.map +1 -0
  21. package/dist/config-DPS6bSYo.d.mts +34 -0
  22. package/dist/config-DPS6bSYo.d.mts.map +1 -0
  23. package/dist/config-P6P5adJg.mjs +287 -0
  24. package/dist/config-P6P5adJg.mjs.map +1 -0
  25. package/dist/console-8bND3mMU.mjs +128 -0
  26. package/dist/console-8bND3mMU.mjs.map +1 -0
  27. package/dist/ecommerce-Cgu4wlux.mjs +993 -0
  28. package/dist/ecommerce-Cgu4wlux.mjs.map +1 -0
  29. package/dist/emitters-6-nKo8i-.mjs +208 -0
  30. package/dist/emitters-6-nKo8i-.mjs.map +1 -0
  31. package/dist/emitters-DldkVSPp.d.mts +12 -0
  32. package/dist/emitters-DldkVSPp.d.mts.map +1 -0
  33. package/dist/index-BfNWgfa5.d.mts +1494 -0
  34. package/dist/index-BfNWgfa5.d.mts.map +1 -0
  35. package/dist/index-BkIWe--N.d.mts +953 -0
  36. package/dist/index-BkIWe--N.d.mts.map +1 -0
  37. package/dist/index-jPzXRn52.d.mts +184 -0
  38. package/dist/index-jPzXRn52.d.mts.map +1 -0
  39. package/dist/manager-DvRRjza6.d.mts +76 -0
  40. package/dist/manager-DvRRjza6.d.mts.map +1 -0
  41. package/dist/posthog-bootstrap-CYfIy_WS.mjs +1769 -0
  42. package/dist/posthog-bootstrap-CYfIy_WS.mjs.map +1 -0
  43. package/dist/posthog-bootstrap-DWxFrxlt.d.mts +81 -0
  44. package/dist/posthog-bootstrap-DWxFrxlt.d.mts.map +1 -0
  45. package/dist/providers-http-client.d.mts +37 -0
  46. package/dist/providers-http-client.d.mts.map +1 -0
  47. package/dist/providers-http-client.mjs +320 -0
  48. package/dist/providers-http-client.mjs.map +1 -0
  49. package/dist/providers-http-server.d.mts +31 -0
  50. package/dist/providers-http-server.d.mts.map +1 -0
  51. package/dist/providers-http-server.mjs +297 -0
  52. package/dist/providers-http-server.mjs.map +1 -0
  53. package/dist/providers-http.d.mts +46 -0
  54. package/dist/providers-http.d.mts.map +1 -0
  55. package/dist/providers-http.mjs +4 -0
  56. package/dist/server-edge.d.mts +9 -0
  57. package/dist/server-edge.d.mts.map +1 -0
  58. package/dist/server-edge.mjs +373 -0
  59. package/dist/server-edge.mjs.map +1 -0
  60. package/dist/server-next.d.mts +67 -0
  61. package/dist/server-next.d.mts.map +1 -0
  62. package/dist/server-next.mjs +193 -0
  63. package/dist/server-next.mjs.map +1 -0
  64. package/dist/server.d.mts +10 -0
  65. package/dist/server.mjs +7 -0
  66. package/dist/service-cYtBBL8x.mjs +945 -0
  67. package/dist/service-cYtBBL8x.mjs.map +1 -0
  68. package/dist/shared.d.mts +16 -0
  69. package/dist/shared.d.mts.map +1 -0
  70. package/dist/shared.mjs +93 -0
  71. package/dist/shared.mjs.map +1 -0
  72. package/dist/types-BxBnNQ0V.d.mts +354 -0
  73. package/dist/types-BxBnNQ0V.d.mts.map +1 -0
  74. package/dist/types-CBvxUEaF.d.mts +216 -0
  75. package/dist/types-CBvxUEaF.d.mts.map +1 -0
  76. package/dist/types.d.mts +4 -0
  77. package/dist/types.mjs +0 -0
  78. package/dist/vercel-types-lwakUfoI.d.mts +102 -0
  79. package/dist/vercel-types-lwakUfoI.d.mts.map +1 -0
  80. package/package.json +129 -0
  81. package/src/client/index.ts +164 -0
  82. package/src/client/manager.ts +71 -0
  83. package/src/client/next/components.tsx +270 -0
  84. package/src/client/next/hooks.ts +217 -0
  85. package/src/client/next/manager.ts +141 -0
  86. package/src/client/next.ts +144 -0
  87. package/src/client-next.ts +101 -0
  88. package/src/client.ts +89 -0
  89. package/src/examples/ai-sdk-patterns.ts +583 -0
  90. package/src/examples/emitter-patterns.ts +476 -0
  91. package/src/examples/nextjs-emitter-patterns.tsx +403 -0
  92. package/src/next/app-router.tsx +564 -0
  93. package/src/next/client.ts +419 -0
  94. package/src/next/index.ts +84 -0
  95. package/src/next/middleware.ts +429 -0
  96. package/src/next/rsc.tsx +300 -0
  97. package/src/next/server.ts +253 -0
  98. package/src/next/types.d.ts +220 -0
  99. package/src/providers/base-provider.ts +419 -0
  100. package/src/providers/console/client.ts +10 -0
  101. package/src/providers/console/index.ts +152 -0
  102. package/src/providers/console/server.ts +6 -0
  103. package/src/providers/console/types.ts +15 -0
  104. package/src/providers/http/client.ts +464 -0
  105. package/src/providers/http/index.ts +30 -0
  106. package/src/providers/http/server.ts +396 -0
  107. package/src/providers/http/types.ts +135 -0
  108. package/src/providers/posthog/client.ts +518 -0
  109. package/src/providers/posthog/index.ts +11 -0
  110. package/src/providers/posthog/server.ts +329 -0
  111. package/src/providers/posthog/types.ts +104 -0
  112. package/src/providers/segment/client.ts +113 -0
  113. package/src/providers/segment/index.ts +11 -0
  114. package/src/providers/segment/server.ts +115 -0
  115. package/src/providers/segment/types.ts +51 -0
  116. package/src/providers/vercel/client.ts +102 -0
  117. package/src/providers/vercel/index.ts +11 -0
  118. package/src/providers/vercel/server.ts +89 -0
  119. package/src/providers/vercel/types.ts +27 -0
  120. package/src/server/index.ts +103 -0
  121. package/src/server/manager.ts +62 -0
  122. package/src/server/next.ts +210 -0
  123. package/src/server-edge.ts +442 -0
  124. package/src/server-next.ts +39 -0
  125. package/src/server.ts +106 -0
  126. package/src/shared/emitters/ai/README.md +981 -0
  127. package/src/shared/emitters/ai/events/agent.ts +130 -0
  128. package/src/shared/emitters/ai/events/artifacts.ts +167 -0
  129. package/src/shared/emitters/ai/events/chat.ts +126 -0
  130. package/src/shared/emitters/ai/events/chatbot-ecommerce.ts +133 -0
  131. package/src/shared/emitters/ai/events/completion.ts +103 -0
  132. package/src/shared/emitters/ai/events/content-generation.ts +347 -0
  133. package/src/shared/emitters/ai/events/conversation.ts +332 -0
  134. package/src/shared/emitters/ai/events/product-features.ts +1402 -0
  135. package/src/shared/emitters/ai/events/streaming.ts +114 -0
  136. package/src/shared/emitters/ai/events/tool.ts +93 -0
  137. package/src/shared/emitters/ai/index.ts +69 -0
  138. package/src/shared/emitters/ai/track-ai-sdk.ts +74 -0
  139. package/src/shared/emitters/ai/track-ai.ts +50 -0
  140. package/src/shared/emitters/ai/types.ts +1041 -0
  141. package/src/shared/emitters/ai/utils.ts +468 -0
  142. package/src/shared/emitters/ecommerce/events/cart-checkout.ts +106 -0
  143. package/src/shared/emitters/ecommerce/events/coupon.ts +49 -0
  144. package/src/shared/emitters/ecommerce/events/engagement.ts +61 -0
  145. package/src/shared/emitters/ecommerce/events/marketplace.ts +119 -0
  146. package/src/shared/emitters/ecommerce/events/order.ts +199 -0
  147. package/src/shared/emitters/ecommerce/events/product.ts +205 -0
  148. package/src/shared/emitters/ecommerce/events/registry.ts +123 -0
  149. package/src/shared/emitters/ecommerce/events/wishlist-sharing.ts +140 -0
  150. package/src/shared/emitters/ecommerce/index.ts +46 -0
  151. package/src/shared/emitters/ecommerce/track-ecommerce.ts +53 -0
  152. package/src/shared/emitters/ecommerce/types.ts +314 -0
  153. package/src/shared/emitters/ecommerce/utils.ts +216 -0
  154. package/src/shared/emitters/emitter-types.ts +974 -0
  155. package/src/shared/emitters/emitters.ts +292 -0
  156. package/src/shared/emitters/helpers.ts +419 -0
  157. package/src/shared/emitters/index.ts +66 -0
  158. package/src/shared/index.ts +142 -0
  159. package/src/shared/ingestion/index.ts +66 -0
  160. package/src/shared/ingestion/schemas.ts +386 -0
  161. package/src/shared/ingestion/service.ts +628 -0
  162. package/src/shared/node22-features.ts +848 -0
  163. package/src/shared/providers/console-provider.ts +160 -0
  164. package/src/shared/types/base-types.ts +54 -0
  165. package/src/shared/types/console-types.ts +19 -0
  166. package/src/shared/types/posthog-types.ts +131 -0
  167. package/src/shared/types/segment-types.ts +15 -0
  168. package/src/shared/types/types.ts +397 -0
  169. package/src/shared/types/vercel-types.ts +19 -0
  170. package/src/shared/utils/config-client.ts +19 -0
  171. package/src/shared/utils/config.ts +250 -0
  172. package/src/shared/utils/emitter-adapter.ts +212 -0
  173. package/src/shared/utils/manager.test.ts +36 -0
  174. package/src/shared/utils/manager.ts +1322 -0
  175. package/src/shared/utils/posthog-bootstrap.ts +136 -0
  176. package/src/shared/utils/posthog-client-utils.ts +48 -0
  177. package/src/shared/utils/posthog-next-utils.ts +282 -0
  178. package/src/shared/utils/posthog-server-utils.ts +210 -0
  179. package/src/shared/utils/rate-limit.ts +289 -0
  180. package/src/shared/utils/security.ts +545 -0
  181. package/src/shared/utils/validation-client.ts +161 -0
  182. package/src/shared/utils/validation.ts +399 -0
  183. package/src/shared.ts +155 -0
  184. 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>;