@reopt-ai/data-contract 0.6.3 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/dist/client.cjs +228 -321
  2. package/dist/client.cjs.map +1 -1
  3. package/dist/client.d.cts +57 -71
  4. package/dist/client.d.cts.map +1 -0
  5. package/dist/client.d.ts +57 -71
  6. package/dist/client.d.ts.map +1 -0
  7. package/dist/client.js +228 -322
  8. package/dist/client.js.map +1 -1
  9. package/dist/control.cjs +158 -54
  10. package/dist/control.cjs.map +1 -1
  11. package/dist/control.d.cts +121 -137
  12. package/dist/control.d.cts.map +1 -0
  13. package/dist/control.d.ts +121 -137
  14. package/dist/control.d.ts.map +1 -0
  15. package/dist/control.js +134 -54
  16. package/dist/control.js.map +1 -1
  17. package/dist/events-BUIeU60t.d.cts +142 -0
  18. package/dist/events-BUIeU60t.d.cts.map +1 -0
  19. package/dist/events-BUIeU60t.d.ts +142 -0
  20. package/dist/events-BUIeU60t.d.ts.map +1 -0
  21. package/dist/events.cjs +110 -15
  22. package/dist/events.cjs.map +1 -1
  23. package/dist/events.d.cts +2 -59
  24. package/dist/events.d.ts +2 -59
  25. package/dist/events.js +101 -15
  26. package/dist/events.js.map +1 -1
  27. package/dist/identity.cjs +150 -55
  28. package/dist/identity.cjs.map +1 -1
  29. package/dist/identity.d.cts +21 -20
  30. package/dist/identity.d.cts.map +1 -0
  31. package/dist/identity.d.ts +21 -20
  32. package/dist/identity.d.ts.map +1 -0
  33. package/dist/identity.js +126 -56
  34. package/dist/identity.js.map +1 -1
  35. package/dist/index.cjs +46 -25
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +37 -54
  38. package/dist/index.d.cts.map +1 -0
  39. package/dist/index.d.ts +37 -54
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +36 -25
  42. package/dist/index.js.map +1 -1
  43. package/dist/ingest.cjs +152 -57
  44. package/dist/ingest.cjs.map +1 -1
  45. package/dist/ingest.d.cts +182 -193
  46. package/dist/ingest.d.cts.map +1 -0
  47. package/dist/ingest.d.ts +182 -193
  48. package/dist/ingest.d.ts.map +1 -0
  49. package/dist/ingest.js +126 -57
  50. package/dist/ingest.js.map +1 -1
  51. package/dist/query.cjs +284 -84
  52. package/dist/query.cjs.map +1 -1
  53. package/dist/query.d.cts +456 -469
  54. package/dist/query.d.cts.map +1 -0
  55. package/dist/query.d.ts +456 -469
  56. package/dist/query.d.ts.map +1 -0
  57. package/dist/query.js +245 -84
  58. package/dist/query.js.map +1 -1
  59. package/dist/report.cjs +104 -74
  60. package/dist/report.cjs.map +1 -1
  61. package/dist/report.d.cts +182 -136
  62. package/dist/report.d.cts.map +1 -0
  63. package/dist/report.d.ts +182 -136
  64. package/dist/report.d.ts.map +1 -0
  65. package/dist/report.js +93 -74
  66. package/dist/report.js.map +1 -1
  67. package/dist/version-B_0qb1_K.cjs +53 -0
  68. package/dist/version-B_0qb1_K.cjs.map +1 -0
  69. package/dist/version-C09Cyf4R.js +12 -0
  70. package/dist/version-C09Cyf4R.js.map +1 -0
  71. package/dist/{version-DJ2Grb_N.d.ts → version-CGujUGWd.d.cts} +5 -3
  72. package/dist/version-CGujUGWd.d.cts.map +1 -0
  73. package/dist/{version-DJ2Grb_N.d.cts → version-CGujUGWd.d.ts} +5 -3
  74. package/dist/version-CGujUGWd.d.ts.map +1 -0
  75. package/package.json +69 -28
  76. package/dist/chunk-3EEANNYN.cjs +0 -62
  77. package/dist/chunk-3EEANNYN.cjs.map +0 -1
  78. package/dist/chunk-7W33YGRO.js +0 -160
  79. package/dist/chunk-7W33YGRO.js.map +0 -1
  80. package/dist/chunk-F2RNXJGO.cjs +0 -19
  81. package/dist/chunk-F2RNXJGO.cjs.map +0 -1
  82. package/dist/chunk-FP2X3PRK.js +0 -62
  83. package/dist/chunk-FP2X3PRK.js.map +0 -1
  84. package/dist/chunk-JCEWUSUM.js +0 -53
  85. package/dist/chunk-JCEWUSUM.js.map +0 -1
  86. package/dist/chunk-L3JPDRVG.cjs +0 -160
  87. package/dist/chunk-L3JPDRVG.cjs.map +0 -1
  88. package/dist/chunk-L4KBQAOO.js +0 -204
  89. package/dist/chunk-L4KBQAOO.js.map +0 -1
  90. package/dist/chunk-NJ4JKNBX.js +0 -361
  91. package/dist/chunk-NJ4JKNBX.js.map +0 -1
  92. package/dist/chunk-ORNTN6AK.cjs +0 -53
  93. package/dist/chunk-ORNTN6AK.cjs.map +0 -1
  94. package/dist/chunk-PSUINLW7.js +0 -19
  95. package/dist/chunk-PSUINLW7.js.map +0 -1
  96. package/dist/chunk-RU26QFM2.js +0 -179
  97. package/dist/chunk-RU26QFM2.js.map +0 -1
  98. package/dist/chunk-XDH5QQYF.cjs +0 -361
  99. package/dist/chunk-XDH5QQYF.cjs.map +0 -1
  100. package/dist/chunk-YCTGHWTP.cjs +0 -204
  101. package/dist/chunk-YCTGHWTP.cjs.map +0 -1
  102. package/dist/chunk-ZI6A3WQP.cjs +0 -179
  103. package/dist/chunk-ZI6A3WQP.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","names":[],"sources":["../src/query.ts"],"mappings":"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"}
package/dist/query.js CHANGED
@@ -1,86 +1,247 @@
1
- import {
2
- QUERY_API_PATHS,
3
- QUERY_ERROR_CODES,
4
- isValidTimeZone,
5
- zBucketStart,
6
- zChannelFilter,
7
- zEventPropertyFilter,
8
- zEventsTimeseriesData,
9
- zEventsTimeseriesInput,
10
- zEventsTimeseriesResponse,
11
- zFunnelData,
12
- zFunnelInput,
13
- zFunnelResponse,
14
- zFunnelStep,
15
- zGranularity,
16
- zQueryEnvelope,
17
- zQueryError,
18
- zQueryErrorCode,
19
- zQueryMeta,
20
- zQuerySource,
21
- zRetentionCell,
22
- zRetentionData,
23
- zRetentionInput,
24
- zRetentionInterval,
25
- zRetentionResponse,
26
- zTimeseriesBreakdown,
27
- zTimeseriesPoint,
28
- zTimezone,
29
- zTrafficDimension,
30
- zTrafficOverviewData,
31
- zTrafficOverviewInput,
32
- zTrafficOverviewResponse,
33
- zTrafficSeriesPoint,
34
- zTrafficSourceRow,
35
- zTrafficSourcesData,
36
- zTrafficSourcesInput,
37
- zTrafficSourcesResponse,
38
- zTrafficTotals
39
- } from "./chunk-NJ4JKNBX.js";
40
- import {
41
- zDate,
42
- zInstant
43
- } from "./chunk-JCEWUSUM.js";
44
- import "./chunk-PSUINLW7.js";
45
- export {
46
- QUERY_API_PATHS,
47
- QUERY_ERROR_CODES,
48
- isValidTimeZone,
49
- zBucketStart,
50
- zChannelFilter,
51
- zDate,
52
- zEventPropertyFilter,
53
- zEventsTimeseriesData,
54
- zEventsTimeseriesInput,
55
- zEventsTimeseriesResponse,
56
- zFunnelData,
57
- zFunnelInput,
58
- zFunnelResponse,
59
- zFunnelStep,
60
- zGranularity,
61
- zInstant,
62
- zQueryEnvelope,
63
- zQueryError,
64
- zQueryErrorCode,
65
- zQueryMeta,
66
- zQuerySource,
67
- zRetentionCell,
68
- zRetentionData,
69
- zRetentionInput,
70
- zRetentionInterval,
71
- zRetentionResponse,
72
- zTimeseriesBreakdown,
73
- zTimeseriesPoint,
74
- zTimezone,
75
- zTrafficDimension,
76
- zTrafficOverviewData,
77
- zTrafficOverviewInput,
78
- zTrafficOverviewResponse,
79
- zTrafficSeriesPoint,
80
- zTrafficSourceRow,
81
- zTrafficSourcesData,
82
- zTrafficSourcesInput,
83
- zTrafficSourcesResponse,
84
- zTrafficTotals
1
+ import { zDate, zInstant } from "./index.js";
2
+ import { z } from "zod";
3
+ //#region src/query.ts
4
+ const zGranularity = z.enum([
5
+ "hour",
6
+ "day",
7
+ "week",
8
+ "month"
9
+ ]);
10
+ const zTimezone = z.string().min(1).max(64).refine(isValidTimeZone, { message: "unknown IANA time zone" });
11
+ function isValidTimeZone(value) {
12
+ try {
13
+ new Intl.DateTimeFormat("en-US", { timeZone: value });
14
+ return true;
15
+ } catch {
16
+ return false;
17
+ }
18
+ }
19
+ const zChannelFilter = z.object({
20
+ referrerTypes: z.array(z.string()).optional(),
21
+ channelTypes: z.array(z.string()).optional(),
22
+ utmSources: z.array(z.string()).optional(),
23
+ utmMediums: z.array(z.string()).optional(),
24
+ utmCampaigns: z.array(z.string()).optional()
25
+ }).optional();
26
+ const zQuerySource = z.enum([
27
+ "rollup",
28
+ "raw",
29
+ "mixed"
30
+ ]);
31
+ const zQueryMeta = z.object({
32
+ projectId: z.string(),
33
+ computedAt: zInstant,
34
+ cacheAgeSeconds: z.number().int().nonnegative(),
35
+ ingestLagSeconds: z.number().int().nonnegative().nullable(),
36
+ ingestLagStatus: z.enum(["known", "unknown"]),
37
+ ingestDeadLetterCount: z.number().int().nonnegative().nullable(),
38
+ cached: z.boolean(),
39
+ timezone: z.string(),
40
+ source: zQuerySource,
41
+ requestId: z.string()
42
+ });
43
+ function zQueryEnvelope(data) {
44
+ return z.object({
45
+ data,
46
+ meta: zQueryMeta
47
+ });
48
+ }
49
+ const zTimeseriesBreakdown = z.object({
50
+ kind: z.literal("property"),
51
+ key: z.string().min(1).max(200),
52
+ topN: z.number().int().min(1).max(100).default(5)
53
+ });
54
+ const zEventPropertyFilter = z.object({
55
+ key: z.string().min(1).max(200),
56
+ operator: z.literal("eq").default("eq"),
57
+ value: z.string().min(1).max(500)
58
+ });
59
+ const zEventsTimeseriesInput = z.object({
60
+ projectId: z.string().min(1),
61
+ startDate: zDate,
62
+ endDate: zDate,
63
+ granularity: zGranularity.default("day"),
64
+ eventName: z.string().min(1).max(200).optional(),
65
+ propertyFilters: z.array(zEventPropertyFilter).max(10).optional(),
66
+ breakdown: zTimeseriesBreakdown.optional(),
67
+ segmentId: z.string().min(1).optional(),
68
+ timezone: zTimezone.optional(),
69
+ includeInternal: z.boolean().default(false)
70
+ }).refine((input) => input.startDate <= input.endDate, {
71
+ message: "endDate must be on or after startDate",
72
+ path: ["endDate"]
73
+ });
74
+ const zBucketStart = z.string().regex(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/, "expected 'YYYY-MM-DD HH:MM:SS'");
75
+ const zTimeseriesPoint = z.object({
76
+ date: zBucketStart,
77
+ count: z.number().int().nonnegative()
78
+ });
79
+ const zEventsTimeseriesData = z.object({
80
+ granularity: zGranularity,
81
+ timezone: z.string(),
82
+ series: z.array(zTimeseriesPoint),
83
+ breakdown: z.array(z.object({
84
+ value: z.string(),
85
+ points: z.array(zTimeseriesPoint)
86
+ })).optional()
87
+ });
88
+ const zEventsTimeseriesResponse = zQueryEnvelope(zEventsTimeseriesData);
89
+ const zFunnelInput = z.object({
90
+ projectId: z.string().min(1),
91
+ steps: z.array(z.string().min(1).max(200)).min(2).max(10),
92
+ startDate: zDate,
93
+ endDate: zDate,
94
+ windowSeconds: z.number().int().min(60).max(2592e3).default(86400),
95
+ segmentId: z.string().min(1).optional(),
96
+ channelFilter: zChannelFilter,
97
+ timezone: zTimezone.optional(),
98
+ includeInternal: z.boolean().default(false)
99
+ }).refine((input) => input.startDate <= input.endDate, {
100
+ message: "endDate must be on or after startDate",
101
+ path: ["endDate"]
102
+ });
103
+ const zFunnelStep = z.object({
104
+ step: z.number().int().min(1),
105
+ name: z.string(),
106
+ users: z.number().int().nonnegative(),
107
+ conversionRate: z.number(),
108
+ dropoffRate: z.number(),
109
+ dropoffUsers: z.number().int().nonnegative()
110
+ });
111
+ const zFunnelData = z.object({
112
+ steps: z.array(zFunnelStep),
113
+ totalUsers: z.number().int().nonnegative(),
114
+ overallConversionRate: z.number()
115
+ });
116
+ const zFunnelResponse = zQueryEnvelope(zFunnelData);
117
+ const zRetentionInterval = z.enum([
118
+ "day",
119
+ "week",
120
+ "month"
121
+ ]);
122
+ const zRetentionInput = z.object({
123
+ projectId: z.string().min(1),
124
+ startDate: zDate,
125
+ endDate: zDate,
126
+ interval: zRetentionInterval.default("day"),
127
+ periods: z.number().int().min(1).max(30).default(7),
128
+ startEvent: z.string().min(1).max(200).optional(),
129
+ returnEvent: z.string().min(1).max(200).optional(),
130
+ retentionType: z.enum(["bounded", "unbounded"]).default("bounded"),
131
+ cohortMode: z.enum(["first-ever", "first-in-window"]).default("first-ever"),
132
+ segmentId: z.string().min(1).optional(),
133
+ channelFilter: zChannelFilter,
134
+ timezone: zTimezone.optional(),
135
+ includeInternal: z.boolean().default(false)
136
+ }).refine((input) => input.startDate <= input.endDate, {
137
+ message: "endDate must be on or after startDate",
138
+ path: ["endDate"]
139
+ });
140
+ const zRetentionCell = z.object({
141
+ period: z.number().int().nonnegative(),
142
+ users: z.number().int().nonnegative(),
143
+ rate: z.number()
144
+ });
145
+ const zRetentionData = z.object({
146
+ matrix: z.array(z.object({
147
+ cohortDate: zBucketStart,
148
+ cohortSize: z.number().int().nonnegative(),
149
+ retention: z.array(zRetentionCell)
150
+ })),
151
+ averageRetention: z.array(z.object({
152
+ period: z.number().int().nonnegative(),
153
+ rate: z.number()
154
+ })),
155
+ interval: zRetentionInterval,
156
+ periods: z.number().int(),
157
+ retentionType: z.enum(["bounded", "unbounded"]),
158
+ timezone: z.string()
159
+ });
160
+ const zRetentionResponse = zQueryEnvelope(zRetentionData);
161
+ const zTrafficOverviewInput = z.object({
162
+ projectId: z.string().min(1),
163
+ startDate: zDate,
164
+ endDate: zDate,
165
+ granularity: zGranularity.default("day"),
166
+ timezone: zTimezone.optional()
167
+ }).refine((input) => input.startDate <= input.endDate, {
168
+ message: "endDate must be on or after startDate",
169
+ path: ["endDate"]
170
+ });
171
+ const zTrafficTotals = z.object({
172
+ sessions: z.number().int().nonnegative(),
173
+ pageviews: z.number().int().nonnegative(),
174
+ newVisitors: z.number().int().nonnegative(),
175
+ returningVisitors: z.number().int().nonnegative(),
176
+ bounceRate: z.number()
177
+ });
178
+ const zTrafficSeriesPoint = zTrafficTotals.extend({ date: zBucketStart });
179
+ const zTrafficOverviewData = z.object({
180
+ granularity: zGranularity,
181
+ timezone: z.string(),
182
+ totals: zTrafficTotals,
183
+ series: z.array(zTrafficSeriesPoint)
184
+ });
185
+ const zTrafficOverviewResponse = zQueryEnvelope(zTrafficOverviewData);
186
+ const zTrafficDimension = z.enum([
187
+ "channel",
188
+ "referrer",
189
+ "utm"
190
+ ]);
191
+ const zTrafficSourcesInput = z.object({
192
+ projectId: z.string().min(1),
193
+ startDate: zDate,
194
+ endDate: zDate,
195
+ dimension: zTrafficDimension,
196
+ limit: z.number().int().min(1).max(100).default(10),
197
+ timezone: zTimezone.optional()
198
+ }).refine((input) => input.startDate <= input.endDate, {
199
+ message: "endDate must be on or after startDate",
200
+ path: ["endDate"]
201
+ });
202
+ const zTrafficSourceRow = zTrafficTotals.extend({
203
+ key: z.string(),
204
+ channelType: z.string().optional(),
205
+ referrerName: z.string().optional(),
206
+ referrerType: z.string().optional(),
207
+ utmSource: z.string().optional(),
208
+ utmMedium: z.string().optional(),
209
+ utmCampaign: z.string().optional()
210
+ });
211
+ const zTrafficSourcesData = z.object({
212
+ dimension: zTrafficDimension,
213
+ timezone: z.string(),
214
+ rows: z.array(zTrafficSourceRow)
215
+ });
216
+ const zTrafficSourcesResponse = zQueryEnvelope(zTrafficSourcesData);
217
+ const QUERY_ERROR_CODES = [
218
+ "unauthorized",
219
+ "project_scope_mismatch",
220
+ "query_scope_missing",
221
+ "validation_failed",
222
+ "unsupported_combination",
223
+ "project_purging",
224
+ "rate_limited",
225
+ "query_timeout",
226
+ "internal_error"
227
+ ];
228
+ const zQueryErrorCode = z.enum(QUERY_ERROR_CODES);
229
+ const zQueryError = z.object({
230
+ status: z.number().int(),
231
+ code: zQueryErrorCode,
232
+ error: z.string(),
233
+ message: z.string().optional(),
234
+ errors: z.unknown().optional(),
235
+ requestId: z.string().optional()
236
+ });
237
+ const QUERY_API_PATHS = {
238
+ eventsTimeseries: "/api/v1/query/events/timeseries",
239
+ funnel: "/api/v1/query/funnel",
240
+ retention: "/api/v1/query/retention",
241
+ trafficOverview: "/api/v1/query/traffic/overview",
242
+ trafficSources: "/api/v1/query/traffic/sources"
85
243
  };
244
+ //#endregion
245
+ export { QUERY_API_PATHS, QUERY_ERROR_CODES, isValidTimeZone, zBucketStart, zChannelFilter, zDate, zEventPropertyFilter, zEventsTimeseriesData, zEventsTimeseriesInput, zEventsTimeseriesResponse, zFunnelData, zFunnelInput, zFunnelResponse, zFunnelStep, zGranularity, zInstant, zQueryEnvelope, zQueryError, zQueryErrorCode, zQueryMeta, zQuerySource, zRetentionCell, zRetentionData, zRetentionInput, zRetentionInterval, zRetentionResponse, zTimeseriesBreakdown, zTimeseriesPoint, zTimezone, zTrafficDimension, zTrafficOverviewData, zTrafficOverviewInput, zTrafficOverviewResponse, zTrafficSeriesPoint, zTrafficSourceRow, zTrafficSourcesData, zTrafficSourcesInput, zTrafficSourcesResponse, zTrafficTotals };
246
+
86
247
  //# sourceMappingURL=query.js.map
package/dist/query.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"file":"query.js","names":[],"sources":["../src/query.ts"],"sourcesContent":["/**\n * `POST /api/v1/query/*` — the read contract.\n *\n * Server credentials, project-scoped: the authenticated client's projectId must\n * equal the `projectId` in the body, or the request is refused. Reads are POSTs\n * because the inputs nest (funnel steps, channel filters) and would not survive\n * a query string; consumers cache on their own side, so HTTP cache semantics\n * buy nothing here.\n *\n * Response shapes mirror the existing dashboard computations exactly — this\n * plane re-exposes them, it does not add new math.\n */\nimport { z } from \"zod\";\nimport { zDate, zInstant } from \"./index.js\";\n\nexport { zDate, zInstant };\n\n/** Bucket width for a time series. */\nexport const zGranularity = z.enum([\"hour\", \"day\", \"week\", \"month\"]);\nexport type Granularity = z.infer<typeof zGranularity>;\n\n/**\n * IANA time zone name, e.g. `Asia/Seoul`. Decides two things at once: where a\n * calendar day starts, and therefore which bucket an event falls in.\n *\n * A Korean brand reading \"23 Aug: 120 visits\" means 23 Aug in Seoul. Computed\n * in UTC, that headline silently covers 23 Aug 09:00 through 24 Aug 09:00 —\n * wrong by nine hours in a way nothing on the page reveals.\n *\n * Validated against the runtime's own zone database rather than a regex, so an\n * unknown name fails here with a clear message instead of deep inside a query.\n */\nexport const zTimezone = z.string().min(1).max(64).refine(isValidTimeZone, { message: \"unknown IANA time zone\" });\n\nexport function isValidTimeZone(value: string): boolean {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: value });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Acquisition-channel filter. Every field is a set — an event matches when its\n * value is in the set; omitted fields do not constrain. Mirrors the dashboard's\n * `channelFilterSchema` field-for-field.\n */\nexport const zChannelFilter = z\n .object({\n referrerTypes: z.array(z.string()).optional(),\n channelTypes: z.array(z.string()).optional(),\n utmSources: z.array(z.string()).optional(),\n utmMediums: z.array(z.string()).optional(),\n utmCampaigns: z.array(z.string()).optional(),\n })\n .optional();\nexport type ChannelFilter = z.infer<typeof zChannelFilter>;\n\n// ─── Envelope ───────────────────────────────────────────────────────────────\n\n/**\n * Staleness is reported as two independent numbers, never as one sum, because\n * the two have different remedies: a stale cache resolves itself at the next\n * TTL, while ingest lag means the read model is genuinely behind and the right\n * response is an \"aggregating\" badge, not a refresh.\n */\nexport const zQuerySource = z.enum([\"rollup\", \"raw\", \"mixed\"]);\nexport type QuerySource = z.infer<typeof zQuerySource>;\n\nexport const zQueryMeta = z.object({\n projectId: z.string(),\n /** When the underlying computation actually ran. On a cache hit, when the cached value was computed. */\n computedAt: zInstant,\n /** Age of the returned computation, in seconds. `0` on a cache miss. */\n cacheAgeSeconds: z.number().int().nonnegative(),\n /**\n * How far behind live materialization was when the computation ran, in\n * seconds. `0` means no live event is pending; `null` means measurement\n * failed and must never be interpreted as fresh.\n *\n * Deliberately not `now - max(events.created_at)` — that conflates \"the\n * pipeline is behind\" with \"this project is quiet\", and grows without bound\n * on an idle project.\n */\n ingestLagSeconds: z.number().int().nonnegative().nullable(),\n /** Whether the freshness measurement itself succeeded. */\n ingestLagStatus: z.enum([\"known\", \"unknown\"]),\n /**\n * Pending events older than the live replay window. Kept separate so an old\n * permanently failing event neither pegs live lag nor disappears behind 0.\n * `null` means the measurement failed.\n */\n ingestDeadLetterCount: z.number().int().nonnegative().nullable(),\n cached: z.boolean(),\n /**\n * The time zone actually used to place bucket and window boundaries — the\n * resolved value, not the requested one. Read it rather than assuming the\n * request was honoured: when no zone is given anywhere it is `\"UTC\"`, and\n * that is exactly the case a consumer needs to notice.\n */\n timezone: z.string(),\n /**\n * Where the numbers came from. `rollup`: pre-aggregated hourly tables;\n * `raw`: a scan of the event/session tables; `mixed`: finished hours from\n * the rollup, the hour still in progress from raw. Diagnostic — the values\n * agree either way — but a consumer that expected `rollup` and sees `raw`\n * has asked for a combination the rollups cannot serve.\n */\n source: zQuerySource,\n requestId: z.string(),\n});\nexport type QueryMeta = z.infer<typeof zQueryMeta>;\n\n/** Every query response is `{ data, meta }`. */\nexport function zQueryEnvelope<T extends z.ZodTypeAny>(data: T) {\n return z.object({ data, meta: zQueryMeta });\n}\n\n// ─── events.timeseries ──────────────────────────────────────────────────────\n\n/**\n * v1 breaks down by `properties` JSON keys only. Built-in columns\n * (country / os / browser / utm_*) have a totals breakdown in the backend but\n * no *time series* variant, and this plane does not add new computations.\n */\nexport const zTimeseriesBreakdown = z.object({\n kind: z.literal(\"property\"),\n key: z.string().min(1).max(200),\n topN: z.number().int().min(1).max(100).default(5),\n});\nexport type TimeseriesBreakdown = z.infer<typeof zTimeseriesBreakdown>;\n\n/** Exact-match filter for a top-level event `properties` key. Multiple filters are ANDed. */\nexport const zEventPropertyFilter = z.object({\n key: z.string().min(1).max(200),\n operator: z.literal(\"eq\").default(\"eq\"),\n value: z.string().min(1).max(500),\n});\nexport type EventPropertyFilter = z.infer<typeof zEventPropertyFilter>;\n\nexport const zEventsTimeseriesInput = z\n .object({\n projectId: z.string().min(1),\n startDate: zDate,\n endDate: zDate,\n granularity: zGranularity.default(\"day\"),\n /** Omit to count every event in the window. */\n eventName: z.string().min(1).max(200).optional(),\n /** Exact matches against top-level `properties` keys. Every item must match. */\n propertyFilters: z.array(zEventPropertyFilter).max(10).optional(),\n breakdown: zTimeseriesBreakdown.optional(),\n /**\n * Cannot be combined with `breakdown` — the backend's breakdown time series\n * takes no segment. Sending both is refused with `unsupported_combination`\n * rather than silently ignoring one of them.\n */\n segmentId: z.string().min(1).optional(),\n /** Omit to fall back to the project's configured zone, then to UTC. */\n timezone: zTimezone.optional(),\n /**\n * Events whose catalogue status is `internal` (operational probes) are\n * left out by default. A probe that needs to find its own event sets this.\n */\n includeInternal: z.boolean().default(false),\n })\n .refine((input) => input.startDate <= input.endDate, {\n message: \"endDate must be on or after startDate\",\n path: [\"endDate\"],\n });\nexport type EventsTimeseriesInput = z.input<typeof zEventsTimeseriesInput>;\n\n/**\n * Bucket start as wall-clock time in `meta.timezone`, `YYYY-MM-DD HH:MM:SS`.\n *\n * Pinned rather than left to the backend, because a consumer keys its chart on\n * this string: an unspecified format is one where two backends, or two\n * granularities, can quietly disagree and produce two different keys for the\n * same bucket.\n *\n * It is wall time, not an instant — for `Asia/Seoul` a day bucket reads\n * `2026-08-24 00:00:00`, which is `2026-08-23T15:00:00Z`. Day, week and month\n * buckets always carry `00:00:00`, so slicing the first ten characters is a\n * safe way to get a date key.\n */\nexport const zBucketStart = z.string().regex(/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/, \"expected 'YYYY-MM-DD HH:MM:SS'\");\n\nexport const zTimeseriesPoint = z.object({\n date: zBucketStart,\n count: z.number().int().nonnegative(),\n});\nexport type TimeseriesPoint = z.infer<typeof zTimeseriesPoint>;\n\nexport const zEventsTimeseriesData = z.object({\n granularity: zGranularity,\n /** Zone the buckets were cut in. Mirrors `meta.timezone`. */\n timezone: z.string(),\n /** Total per bucket. Always present, with or without a breakdown. */\n series: z.array(zTimeseriesPoint),\n /** Present only when `breakdown` was requested: the top-N values, each with its own series. */\n breakdown: z\n .array(\n z.object({\n value: z.string(),\n points: z.array(zTimeseriesPoint),\n })\n )\n .optional(),\n});\nexport type EventsTimeseriesData = z.infer<typeof zEventsTimeseriesData>;\n\nexport const zEventsTimeseriesResponse = zQueryEnvelope(zEventsTimeseriesData);\nexport type EventsTimeseriesResponse = z.infer<typeof zEventsTimeseriesResponse>;\n\n// ─── funnel ─────────────────────────────────────────────────────────────────\n\nexport const zFunnelInput = z\n .object({\n projectId: z.string().min(1),\n /** Ordered event names. A user counts at step k if they reached at least step k. */\n steps: z.array(z.string().min(1).max(200)).min(2).max(10),\n startDate: zDate,\n endDate: zDate,\n /** Max seconds between the first and last step for a conversion to count. Default 24h. */\n windowSeconds: z.number().int().min(60).max(2_592_000).default(86_400),\n segmentId: z.string().min(1).optional(),\n channelFilter: zChannelFilter,\n /**\n * Decides where `startDate` / `endDate` fall. A funnel has no buckets, so\n * this only moves the window — but a nine-hour window shift changes who is\n * in the funnel.\n */\n timezone: zTimezone.optional(),\n /** Accepted for symmetry with events.timeseries; funnel steps are named explicitly, so nothing is filtered. */\n includeInternal: z.boolean().default(false),\n })\n .refine((input) => input.startDate <= input.endDate, {\n message: \"endDate must be on or after startDate\",\n path: [\"endDate\"],\n });\nexport type FunnelInput = z.input<typeof zFunnelInput>;\n\nexport const zFunnelStep = z.object({\n step: z.number().int().min(1),\n name: z.string(),\n users: z.number().int().nonnegative(),\n /** Percent of the previous step that reached this one. `100` for step 1. */\n conversionRate: z.number(),\n /** Percent of the previous step that did not. `0` for step 1. */\n dropoffRate: z.number(),\n dropoffUsers: z.number().int().nonnegative(),\n});\n\nexport const zFunnelData = z.object({\n steps: z.array(zFunnelStep),\n totalUsers: z.number().int().nonnegative(),\n /** Percent of step-1 users that reached the last step. */\n overallConversionRate: z.number(),\n});\nexport type FunnelData = z.infer<typeof zFunnelData>;\n\nexport const zFunnelResponse = zQueryEnvelope(zFunnelData);\nexport type FunnelResponse = z.infer<typeof zFunnelResponse>;\n\n// ─── retention ──────────────────────────────────────────────────────────────\n\nexport const zRetentionInterval = z.enum([\"day\", \"week\", \"month\"]);\n\nexport const zRetentionInput = z\n .object({\n projectId: z.string().min(1),\n startDate: zDate,\n endDate: zDate,\n interval: zRetentionInterval.default(\"day\"),\n periods: z.number().int().min(1).max(30).default(7),\n startEvent: z.string().min(1).max(200).optional(),\n returnEvent: z.string().min(1).max(200).optional(),\n /** `bounded`: returned in exactly period N. `unbounded`: returned in period N or later. */\n retentionType: z.enum([\"bounded\", \"unbounded\"]).default(\"bounded\"),\n /**\n * `first-ever` (default): the cohort is everyone whose true first activity\n * landed in the window, read from the first-seen aggregate. `startEvent`,\n * `segmentId` and `channelFilter` then constrain only the *returning* side.\n * `first-in-window`: the cohort is selected by scanning events in the window\n * with all filters applied. Slower, but filters apply to cohort selection.\n */\n cohortMode: z.enum([\"first-ever\", \"first-in-window\"]).default(\"first-ever\"),\n segmentId: z.string().min(1).optional(),\n channelFilter: zChannelFilter,\n /**\n * Decides where a cohort day starts, and so which period a return falls in.\n *\n * Honoured under both cohort modes. Note that a non-UTC zone makes\n * `first-ever` read raw events instead of its daily rollup — the rollup is\n * cut on UTC days and cannot be re-cut after the fact — so expect a slower\n * query in exchange for cohorts that match the reader's calendar.\n */\n timezone: zTimezone.optional(),\n /** Accepted for symmetry with events.timeseries; retention reads named or all-event activity and does not yet apply the internal filter. */\n includeInternal: z.boolean().default(false),\n })\n .refine((input) => input.startDate <= input.endDate, {\n message: \"endDate must be on or after startDate\",\n path: [\"endDate\"],\n });\nexport type RetentionInput = z.input<typeof zRetentionInput>;\n\nexport const zRetentionCell = z.object({\n /** `0` is the cohort's own period. */\n period: z.number().int().nonnegative(),\n users: z.number().int().nonnegative(),\n /** Percent of `cohortSize`. */\n rate: z.number(),\n});\n\nexport const zRetentionData = z.object({\n matrix: z.array(\n z.object({\n /** Cohort bucket start, same shape and zone as {@link zBucketStart}. */\n cohortDate: zBucketStart,\n cohortSize: z.number().int().nonnegative(),\n /** Length is `periods + 1`, index-aligned to `period`. */\n retention: z.array(zRetentionCell),\n })\n ),\n /** Unweighted mean rate per period across cohorts. */\n averageRetention: z.array(z.object({ period: z.number().int().nonnegative(), rate: z.number() })),\n interval: zRetentionInterval,\n periods: z.number().int(),\n retentionType: z.enum([\"bounded\", \"unbounded\"]),\n /** Zone the cohort days were cut in. Mirrors `meta.timezone`. */\n timezone: z.string(),\n});\nexport type RetentionData = z.infer<typeof zRetentionData>;\n\nexport const zRetentionResponse = zQueryEnvelope(zRetentionData);\nexport type RetentionResponse = z.infer<typeof zRetentionResponse>;\n\n// ─── traffic ────────────────────────────────────────────────────────────────\n\n/**\n * Session-level traffic for a brand site, served from the hourly rollups.\n * `newVisitors` counts sessions whose device was first seen inside them;\n * `returningVisitors` is the rest. Both are session counts, not people —\n * \"visitor\" is the vocabulary the dashboards already use.\n */\nexport const zTrafficOverviewInput = z\n .object({\n projectId: z.string().min(1),\n startDate: zDate,\n endDate: zDate,\n granularity: zGranularity.default(\"day\"),\n timezone: zTimezone.optional(),\n })\n .refine((input) => input.startDate <= input.endDate, {\n message: \"endDate must be on or after startDate\",\n path: [\"endDate\"],\n });\nexport type TrafficOverviewInput = z.input<typeof zTrafficOverviewInput>;\n\nexport const zTrafficTotals = z.object({\n sessions: z.number().int().nonnegative(),\n pageviews: z.number().int().nonnegative(),\n newVisitors: z.number().int().nonnegative(),\n returningVisitors: z.number().int().nonnegative(),\n /** Percent of sessions that bounced, two decimals. */\n bounceRate: z.number(),\n});\nexport type TrafficTotals = z.infer<typeof zTrafficTotals>;\n\nexport const zTrafficSeriesPoint = zTrafficTotals.extend({ date: zBucketStart });\n\nexport const zTrafficOverviewData = z.object({\n granularity: zGranularity,\n timezone: z.string(),\n totals: zTrafficTotals,\n series: z.array(zTrafficSeriesPoint),\n});\nexport type TrafficOverviewData = z.infer<typeof zTrafficOverviewData>;\nexport const zTrafficOverviewResponse = zQueryEnvelope(zTrafficOverviewData);\nexport type TrafficOverviewResponse = z.infer<typeof zTrafficOverviewResponse>;\n\nexport const zTrafficDimension = z.enum([\"channel\", \"referrer\", \"utm\"]);\nexport type TrafficDimension = z.infer<typeof zTrafficDimension>;\n\nexport const zTrafficSourcesInput = z\n .object({\n projectId: z.string().min(1),\n startDate: zDate,\n endDate: zDate,\n /** `channel`: channel_type · `referrer`: referrer name+type · `utm`: source/medium/campaign. */\n dimension: zTrafficDimension,\n limit: z.number().int().min(1).max(100).default(10),\n timezone: zTimezone.optional(),\n })\n .refine((input) => input.startDate <= input.endDate, {\n message: \"endDate must be on or after startDate\",\n path: [\"endDate\"],\n });\nexport type TrafficSourcesInput = z.input<typeof zTrafficSourcesInput>;\n\nexport const zTrafficSourceRow = zTrafficTotals.extend({\n /** Display key for the row: the channel, the referrer name, or `source / medium / campaign`. */\n key: z.string(),\n channelType: z.string().optional(),\n referrerName: z.string().optional(),\n referrerType: z.string().optional(),\n utmSource: z.string().optional(),\n utmMedium: z.string().optional(),\n utmCampaign: z.string().optional(),\n});\nexport type TrafficSourceRow = z.infer<typeof zTrafficSourceRow>;\n\nexport const zTrafficSourcesData = z.object({\n dimension: zTrafficDimension,\n timezone: z.string(),\n /** Ordered by sessions, descending. */\n rows: z.array(zTrafficSourceRow),\n});\nexport type TrafficSourcesData = z.infer<typeof zTrafficSourcesData>;\nexport const zTrafficSourcesResponse = zQueryEnvelope(zTrafficSourcesData);\nexport type TrafficSourcesResponse = z.infer<typeof zTrafficSourcesResponse>;\n\n// ─── Errors ─────────────────────────────────────────────────────────────────\n\nexport const QUERY_ERROR_CODES = [\n /** 401 — unknown or mismatched credentials. */\n \"unauthorized\",\n /** 403 — the credential's project is not the project asked about. */\n \"project_scope_mismatch\",\n /** 403 — the credential lacks the `query` scope. Provision a query-scoped client. */\n \"query_scope_missing\",\n /** 400 — input failed the schema. `errors` carries the zod issues. */\n \"validation_failed\",\n /** 400 — inputs are individually valid but cannot be served together (e.g. breakdown + segmentId). */\n \"unsupported_combination\",\n /** 410 — the project is being deleted. Permanent; stop asking. */\n \"project_purging\",\n /** 429 — per-credential query rate limit. `Retry-After` set. */\n \"rate_limited\",\n /** 504 — the analytics backend exceeded its statement timeout. Narrow the window. */\n \"query_timeout\",\n /** 500 — unexpected server failure. */\n \"internal_error\",\n] as const;\nexport const zQueryErrorCode = z.enum(QUERY_ERROR_CODES);\nexport type QueryErrorCode = z.infer<typeof zQueryErrorCode>;\n\nexport const zQueryError = z.object({\n status: z.number().int(),\n code: zQueryErrorCode,\n error: z.string(),\n message: z.string().optional(),\n errors: z.unknown().optional(),\n requestId: z.string().optional(),\n});\nexport type QueryError = z.infer<typeof zQueryError>;\n\n/** Paths, so the client and the route handlers cannot drift apart. */\nexport const QUERY_API_PATHS = {\n eventsTimeseries: \"/api/v1/query/events/timeseries\",\n funnel: \"/api/v1/query/funnel\",\n retention: \"/api/v1/query/retention\",\n trafficOverview: \"/api/v1/query/traffic/overview\",\n trafficSources: \"/api/v1/query/traffic/sources\",\n} as const;\n"],"mappings":"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"}
package/dist/report.cjs CHANGED
@@ -1,85 +1,115 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/report.ts
2
- var _zod = require('zod');
3
- var REPORT_SPEC_VERSION = 1;
4
- var zReportRange = _zod.z.string().regex(/^\d+[dhm]$/, "expected a relative range such as 7d or 24h");
5
- var zReportInterval = _zod.z.enum(["minute", "hour", "day", "week", "month"]);
6
- var zLegacyChartType = _zod.z.enum([
7
- "linear",
8
- "bar",
9
- "pie",
10
- "metric",
11
- "area",
12
- "gauge",
13
- "scatter",
14
- "table",
15
- "sparkline"
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let zod = require("zod");
3
+ //#region src/report.ts
4
+ const REPORT_SPEC_VERSION = 1;
5
+ const zReportRange = zod.z.string().regex(/^\d+[dhm]$/, "expected a relative range such as 7d or 24h");
6
+ const zReportInterval = zod.z.enum([
7
+ "minute",
8
+ "hour",
9
+ "day",
10
+ "week",
11
+ "month"
16
12
  ]);
17
- var zCommon = {
18
- version: _zod.z.literal(REPORT_SPEC_VERSION),
19
- range: zReportRange.default("30d"),
20
- segmentId: _zod.z.string().min(1).optional()
13
+ const zLegacyChartType = zod.z.enum([
14
+ "linear",
15
+ "bar",
16
+ "pie",
17
+ "metric",
18
+ "area",
19
+ "gauge",
20
+ "scatter",
21
+ "table",
22
+ "sparkline"
23
+ ]);
24
+ const zCommon = {
25
+ version: zod.z.literal(1),
26
+ range: zReportRange.default("30d"),
27
+ segmentId: zod.z.string().min(1).optional()
21
28
  };
22
- var zTimeseriesReportSpec = _zod.z.object({
23
- ...zCommon,
24
- kind: _zod.z.literal("timeseries"),
25
- chartType: zLegacyChartType,
26
- interval: zReportInterval,
27
- events: _zod.z.array(_zod.z.object({ name: _zod.z.string().min(1).max(200) })).min(1).max(20),
28
- breakdowns: _zod.z.array(_zod.z.string().min(1).max(200)).max(5).default([]),
29
- comparePrevious: _zod.z.boolean().default(false)
29
+ const zTimeseriesReportSpec = zod.z.object({
30
+ ...zCommon,
31
+ kind: zod.z.literal("timeseries"),
32
+ chartType: zLegacyChartType,
33
+ interval: zReportInterval,
34
+ events: zod.z.array(zod.z.object({ name: zod.z.string().min(1).max(200) })).min(1).max(20),
35
+ breakdowns: zod.z.array(zod.z.string().min(1).max(200)).max(5).default([]),
36
+ comparePrevious: zod.z.boolean().default(false)
37
+ });
38
+ const zFunnelReportSpec = zod.z.object({
39
+ ...zCommon,
40
+ kind: zod.z.literal("funnel"),
41
+ steps: zod.z.array(zod.z.string().min(1).max(200)).min(2).max(10),
42
+ windowSeconds: zod.z.number().int().min(60).max(2592e3).default(86400)
30
43
  });
31
- var zFunnelReportSpec = _zod.z.object({
32
- ...zCommon,
33
- kind: _zod.z.literal("funnel"),
34
- steps: _zod.z.array(_zod.z.string().min(1).max(200)).min(2).max(10),
35
- windowSeconds: _zod.z.number().int().min(60).max(2592e3).default(86400)
44
+ const zRetentionReportSpec = zod.z.object({
45
+ ...zCommon,
46
+ kind: zod.z.literal("retention"),
47
+ interval: zod.z.enum([
48
+ "day",
49
+ "week",
50
+ "month"
51
+ ]).default("day"),
52
+ periods: zod.z.number().int().min(1).max(30).default(7),
53
+ startEvent: zod.z.string().min(1).max(200).optional(),
54
+ returnEvent: zod.z.string().min(1).max(200).optional(),
55
+ retentionType: zod.z.enum(["bounded", "unbounded"]).default("bounded"),
56
+ cohortMode: zod.z.enum(["first-ever", "first-in-window"]).default("first-ever")
36
57
  });
37
- var zRetentionReportSpec = _zod.z.object({
38
- ...zCommon,
39
- kind: _zod.z.literal("retention"),
40
- interval: _zod.z.enum(["day", "week", "month"]).default("day"),
41
- periods: _zod.z.number().int().min(1).max(30).default(7),
42
- startEvent: _zod.z.string().min(1).max(200).optional(),
43
- returnEvent: _zod.z.string().min(1).max(200).optional(),
44
- retentionType: _zod.z.enum(["bounded", "unbounded"]).default("bounded"),
45
- cohortMode: _zod.z.enum(["first-ever", "first-in-window"]).default("first-ever")
58
+ const zPathReportSpec = zod.z.object({
59
+ ...zCommon,
60
+ kind: zod.z.literal("path"),
61
+ limit: zod.z.number().int().min(1).max(100).default(30),
62
+ startPage: zod.z.string().max(2e3).optional(),
63
+ endPage: zod.z.string().max(2e3).optional()
46
64
  });
47
- var zPathReportSpec = _zod.z.object({
48
- ...zCommon,
49
- kind: _zod.z.literal("path"),
50
- limit: _zod.z.number().int().min(1).max(100).default(30),
51
- startPage: _zod.z.string().max(2e3).optional(),
52
- endPage: _zod.z.string().max(2e3).optional()
65
+ const zErrorIssuesTopReportSpec = zod.z.object({
66
+ ...zCommon,
67
+ kind: zod.z.literal("error_issues_top"),
68
+ limit: zod.z.union([zod.z.literal(5), zod.z.literal(10)]).default(5),
69
+ sort: zod.z.enum([
70
+ "occurrences",
71
+ "users",
72
+ "lastSeen"
73
+ ]).default("occurrences"),
74
+ statuses: zod.z.array(zod.z.enum([
75
+ "active",
76
+ "resolved",
77
+ "pending_release",
78
+ "suppressed",
79
+ "archived"
80
+ ])).min(1).max(5).default(["active"])
53
81
  });
54
- var zReportSpec = _zod.z.discriminatedUnion("kind", [
55
- zTimeseriesReportSpec,
56
- zFunnelReportSpec,
57
- zRetentionReportSpec,
58
- zPathReportSpec
82
+ const zReportSpec = zod.z.discriminatedUnion("kind", [
83
+ zTimeseriesReportSpec,
84
+ zFunnelReportSpec,
85
+ zRetentionReportSpec,
86
+ zPathReportSpec,
87
+ zErrorIssuesTopReportSpec
59
88
  ]);
60
89
  function legacyReportToSpec(input) {
61
- const events = _zod.z.array(_zod.z.object({ name: _zod.z.string().min(1).max(200) })).safeParse(input.events);
62
- const breakdowns = _zod.z.array(_zod.z.string().min(1).max(200)).safeParse(input.breakdowns);
63
- return zTimeseriesReportSpec.parse({
64
- version: REPORT_SPEC_VERSION,
65
- kind: "timeseries",
66
- chartType: input.chartType,
67
- interval: input.interval,
68
- range: input.range,
69
- events: events.success && events.data.length > 0 ? events.data : [{ name: "$pageview" }],
70
- breakdowns: breakdowns.success ? breakdowns.data : []
71
- });
90
+ const events = zod.z.array(zod.z.object({ name: zod.z.string().min(1).max(200) })).safeParse(input.events);
91
+ const breakdowns = zod.z.array(zod.z.string().min(1).max(200)).safeParse(input.breakdowns);
92
+ return zTimeseriesReportSpec.parse({
93
+ version: 1,
94
+ kind: "timeseries",
95
+ chartType: input.chartType,
96
+ interval: input.interval,
97
+ range: input.range,
98
+ events: events.success && events.data.length > 0 ? events.data : [{ name: "$pageview" }],
99
+ breakdowns: breakdowns.success ? breakdowns.data : []
100
+ });
72
101
  }
102
+ //#endregion
103
+ exports.REPORT_SPEC_VERSION = REPORT_SPEC_VERSION;
104
+ exports.legacyReportToSpec = legacyReportToSpec;
105
+ exports.zErrorIssuesTopReportSpec = zErrorIssuesTopReportSpec;
106
+ exports.zFunnelReportSpec = zFunnelReportSpec;
107
+ exports.zLegacyChartType = zLegacyChartType;
108
+ exports.zPathReportSpec = zPathReportSpec;
109
+ exports.zReportInterval = zReportInterval;
110
+ exports.zReportRange = zReportRange;
111
+ exports.zReportSpec = zReportSpec;
112
+ exports.zRetentionReportSpec = zRetentionReportSpec;
113
+ exports.zTimeseriesReportSpec = zTimeseriesReportSpec;
73
114
 
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
- exports.REPORT_SPEC_VERSION = REPORT_SPEC_VERSION; exports.legacyReportToSpec = legacyReportToSpec; exports.zFunnelReportSpec = zFunnelReportSpec; exports.zLegacyChartType = zLegacyChartType; exports.zPathReportSpec = zPathReportSpec; exports.zReportInterval = zReportInterval; exports.zReportRange = zReportRange; exports.zReportSpec = zReportSpec; exports.zRetentionReportSpec = zRetentionReportSpec; exports.zTimeseriesReportSpec = zTimeseriesReportSpec;
85
115
  //# sourceMappingURL=report.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/eric/reopt-ai/reopt-data/packages/data-contract/dist/report.cjs","../src/report.ts"],"names":[],"mappings":"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","file":"/Users/eric/reopt-ai/reopt-data/packages/data-contract/dist/report.cjs","sourcesContent":[null,"import { z } from \"zod\";\n\nexport const REPORT_SPEC_VERSION = 1 as const;\n\nexport const zReportRange = z.string().regex(/^\\d+[dhm]$/, \"expected a relative range such as 7d or 24h\");\nexport const zReportInterval = z.enum([\"minute\", \"hour\", \"day\", \"week\", \"month\"]);\nexport const zLegacyChartType = z.enum([\n \"linear\",\n \"bar\",\n \"pie\",\n \"metric\",\n \"area\",\n \"gauge\",\n \"scatter\",\n \"table\",\n \"sparkline\",\n]);\n\nconst zCommon = {\n version: z.literal(REPORT_SPEC_VERSION),\n range: zReportRange.default(\"30d\"),\n segmentId: z.string().min(1).optional(),\n};\n\nexport const zTimeseriesReportSpec = z.object({\n ...zCommon,\n kind: z.literal(\"timeseries\"),\n chartType: zLegacyChartType,\n interval: zReportInterval,\n events: z\n .array(z.object({ name: z.string().min(1).max(200) }))\n .min(1)\n .max(20),\n breakdowns: z.array(z.string().min(1).max(200)).max(5).default([]),\n comparePrevious: z.boolean().default(false),\n});\n\nexport const zFunnelReportSpec = z.object({\n ...zCommon,\n kind: z.literal(\"funnel\"),\n steps: z.array(z.string().min(1).max(200)).min(2).max(10),\n windowSeconds: z.number().int().min(60).max(2_592_000).default(86_400),\n});\n\nexport const zRetentionReportSpec = z.object({\n ...zCommon,\n kind: z.literal(\"retention\"),\n interval: z.enum([\"day\", \"week\", \"month\"]).default(\"day\"),\n periods: z.number().int().min(1).max(30).default(7),\n startEvent: z.string().min(1).max(200).optional(),\n returnEvent: z.string().min(1).max(200).optional(),\n retentionType: z.enum([\"bounded\", \"unbounded\"]).default(\"bounded\"),\n cohortMode: z.enum([\"first-ever\", \"first-in-window\"]).default(\"first-ever\"),\n});\n\nexport const zPathReportSpec = z.object({\n ...zCommon,\n kind: z.literal(\"path\"),\n limit: z.number().int().min(1).max(100).default(30),\n startPage: z.string().max(2_000).optional(),\n endPage: z.string().max(2_000).optional(),\n});\n\nexport const zReportSpec = z.discriminatedUnion(\"kind\", [\n zTimeseriesReportSpec,\n zFunnelReportSpec,\n zRetentionReportSpec,\n zPathReportSpec,\n]);\n\nexport type ReportSpec = z.infer<typeof zReportSpec>;\nexport type TimeseriesReportSpec = z.infer<typeof zTimeseriesReportSpec>;\n\n/** Convert a pre-ReportSpec row into the canonical v1 representation. */\nexport function legacyReportToSpec(input: {\n chartType: z.infer<typeof zLegacyChartType>;\n interval: z.infer<typeof zReportInterval>;\n range: string;\n events: unknown;\n breakdowns: unknown;\n}): TimeseriesReportSpec {\n const events = z.array(z.object({ name: z.string().min(1).max(200) })).safeParse(input.events);\n const breakdowns = z.array(z.string().min(1).max(200)).safeParse(input.breakdowns);\n return zTimeseriesReportSpec.parse({\n version: REPORT_SPEC_VERSION,\n kind: \"timeseries\",\n chartType: input.chartType,\n interval: input.interval,\n range: input.range,\n events: events.success && events.data.length > 0 ? events.data : [{ name: \"$pageview\" }],\n breakdowns: breakdowns.success ? breakdowns.data : [],\n });\n}\n"]}
1
+ {"version":3,"file":"report.cjs","names":["z"],"sources":["../src/report.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const REPORT_SPEC_VERSION = 1 as const;\n\nexport const zReportRange = z.string().regex(/^\\d+[dhm]$/, \"expected a relative range such as 7d or 24h\");\nexport const zReportInterval = z.enum([\"minute\", \"hour\", \"day\", \"week\", \"month\"]);\nexport const zLegacyChartType = z.enum([\n \"linear\",\n \"bar\",\n \"pie\",\n \"metric\",\n \"area\",\n \"gauge\",\n \"scatter\",\n \"table\",\n \"sparkline\",\n]);\n\nconst zCommon = {\n version: z.literal(REPORT_SPEC_VERSION),\n range: zReportRange.default(\"30d\"),\n segmentId: z.string().min(1).optional(),\n};\n\nexport const zTimeseriesReportSpec = z.object({\n ...zCommon,\n kind: z.literal(\"timeseries\"),\n chartType: zLegacyChartType,\n interval: zReportInterval,\n events: z\n .array(z.object({ name: z.string().min(1).max(200) }))\n .min(1)\n .max(20),\n breakdowns: z.array(z.string().min(1).max(200)).max(5).default([]),\n comparePrevious: z.boolean().default(false),\n});\n\nexport const zFunnelReportSpec = z.object({\n ...zCommon,\n kind: z.literal(\"funnel\"),\n steps: z.array(z.string().min(1).max(200)).min(2).max(10),\n windowSeconds: z.number().int().min(60).max(2_592_000).default(86_400),\n});\n\nexport const zRetentionReportSpec = z.object({\n ...zCommon,\n kind: z.literal(\"retention\"),\n interval: z.enum([\"day\", \"week\", \"month\"]).default(\"day\"),\n periods: z.number().int().min(1).max(30).default(7),\n startEvent: z.string().min(1).max(200).optional(),\n returnEvent: z.string().min(1).max(200).optional(),\n retentionType: z.enum([\"bounded\", \"unbounded\"]).default(\"bounded\"),\n cohortMode: z.enum([\"first-ever\", \"first-in-window\"]).default(\"first-ever\"),\n});\n\nexport const zPathReportSpec = z.object({\n ...zCommon,\n kind: z.literal(\"path\"),\n limit: z.number().int().min(1).max(100).default(30),\n startPage: z.string().max(2_000).optional(),\n endPage: z.string().max(2_000).optional(),\n});\n\n/**\n * The issues throwing hardest, as a dashboard tile.\n *\n * The only spec kind with no `events`: it reads issues, which are rows in\n * Postgres joined to occurrence volumes, not an event query. `range` is\n * inherited from `zCommon` and is what the tile counts occurrences over.\n */\nexport const zErrorIssuesTopReportSpec = z.object({\n ...zCommon,\n kind: z.literal(\"error_issues_top\"),\n limit: z.union([z.literal(5), z.literal(10)]).default(5),\n sort: z.enum([\"occurrences\", \"users\", \"lastSeen\"]).default(\"occurrences\"),\n /**\n * Issue states the tile counts. Defaults to `active` alone: a dashboard tile\n * is a thing somebody glances at to decide whether to act, and resolved\n * issues are exactly the ones already decided.\n */\n statuses: z\n .array(z.enum([\"active\", \"resolved\", \"pending_release\", \"suppressed\", \"archived\"]))\n .min(1)\n .max(5)\n .default([\"active\"]),\n});\n\nexport const zReportSpec = z.discriminatedUnion(\"kind\", [\n zTimeseriesReportSpec,\n zFunnelReportSpec,\n zRetentionReportSpec,\n zPathReportSpec,\n zErrorIssuesTopReportSpec,\n]);\n\nexport type ReportSpec = z.infer<typeof zReportSpec>;\nexport type TimeseriesReportSpec = z.infer<typeof zTimeseriesReportSpec>;\nexport type ErrorIssuesTopReportSpec = z.infer<typeof zErrorIssuesTopReportSpec>;\n\n/** Convert a pre-ReportSpec row into the canonical v1 representation. */\nexport function legacyReportToSpec(input: {\n chartType: z.infer<typeof zLegacyChartType>;\n interval: z.infer<typeof zReportInterval>;\n range: string;\n events: unknown;\n breakdowns: unknown;\n}): TimeseriesReportSpec {\n const events = z.array(z.object({ name: z.string().min(1).max(200) })).safeParse(input.events);\n const breakdowns = z.array(z.string().min(1).max(200)).safeParse(input.breakdowns);\n return zTimeseriesReportSpec.parse({\n version: REPORT_SPEC_VERSION,\n kind: \"timeseries\",\n chartType: input.chartType,\n interval: input.interval,\n range: input.range,\n events: events.success && events.data.length > 0 ? events.data : [{ name: \"$pageview\" }],\n breakdowns: breakdowns.success ? breakdowns.data : [],\n });\n}\n"],"mappings":"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"}