@iann29/rastro 0.1.0-alpha.3 → 0.1.0-alpha.4

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 (86) hide show
  1. package/README.md +264 -51
  2. package/agent/integration.md +651 -0
  3. package/agent/manifest.json +183 -0
  4. package/agent/manifest.schema.json +405 -0
  5. package/dist/client/federation.d.ts +205 -0
  6. package/dist/client/federation.d.ts.map +1 -0
  7. package/dist/client/federation.js +179 -0
  8. package/dist/client/federation.js.map +1 -0
  9. package/dist/client/index.d.ts +1600 -8
  10. package/dist/client/index.d.ts.map +1 -1
  11. package/dist/client/index.js +210 -2
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/component/_generated/api.d.ts +4 -0
  14. package/dist/component/_generated/api.d.ts.map +1 -1
  15. package/dist/component/_generated/api.js.map +1 -1
  16. package/dist/component/_generated/component.d.ts +151 -1
  17. package/dist/component/_generated/component.d.ts.map +1 -1
  18. package/dist/component/cardinality.d.ts +12 -0
  19. package/dist/component/cardinality.d.ts.map +1 -0
  20. package/dist/component/cardinality.js +94 -0
  21. package/dist/component/cardinality.js.map +1 -0
  22. package/dist/component/constants.d.ts +10 -0
  23. package/dist/component/constants.d.ts.map +1 -1
  24. package/dist/component/constants.js +10 -0
  25. package/dist/component/constants.js.map +1 -1
  26. package/dist/component/coverage.d.ts +18 -0
  27. package/dist/component/coverage.d.ts.map +1 -0
  28. package/dist/component/coverage.js +19 -0
  29. package/dist/component/coverage.js.map +1 -0
  30. package/dist/component/errors.d.ts +1 -1
  31. package/dist/component/errors.d.ts.map +1 -1
  32. package/dist/component/errors.js.map +1 -1
  33. package/dist/component/http.d.ts.map +1 -1
  34. package/dist/component/http.js +46 -8
  35. package/dist/component/http.js.map +1 -1
  36. package/dist/component/ingest.d.ts.map +1 -1
  37. package/dist/component/ingest.js +238 -18
  38. package/dist/component/ingest.js.map +1 -1
  39. package/dist/component/live.d.ts.map +1 -1
  40. package/dist/component/live.js +6 -3
  41. package/dist/component/live.js.map +1 -1
  42. package/dist/component/reports.d.ts +111 -2
  43. package/dist/component/reports.d.ts.map +1 -1
  44. package/dist/component/reports.js +639 -78
  45. package/dist/component/reports.js.map +1 -1
  46. package/dist/component/retention.d.ts +75 -1
  47. package/dist/component/retention.d.ts.map +1 -1
  48. package/dist/component/retention.js +517 -54
  49. package/dist/component/retention.js.map +1 -1
  50. package/dist/component/sanitize.d.ts +4 -1
  51. package/dist/component/sanitize.d.ts.map +1 -1
  52. package/dist/component/sanitize.js +9 -4
  53. package/dist/component/sanitize.js.map +1 -1
  54. package/dist/component/schema.d.ts +187 -1
  55. package/dist/component/schema.js +100 -1
  56. package/dist/component/schema.js.map +1 -1
  57. package/dist/component/sites.d.ts.map +1 -1
  58. package/dist/component/sites.js +5 -1
  59. package/dist/component/sites.js.map +1 -1
  60. package/dist/component/validators.d.ts +26 -1
  61. package/dist/component/validators.d.ts.map +1 -1
  62. package/dist/component/validators.js +7 -0
  63. package/dist/component/validators.js.map +1 -1
  64. package/docs/benchmarks/2026-08-20-realistic.md +4 -4
  65. package/docs/benchmarks/2026-08-21-formal-certification.md +333 -0
  66. package/docs/federation-setup.md +395 -0
  67. package/docs/federation.md +258 -0
  68. package/docs/upgrading.md +130 -0
  69. package/llms.txt +65 -0
  70. package/package.json +32 -6
  71. package/scripts/generate-federation-keys.mjs +20 -0
  72. package/src/component/_generated/api.ts +4 -0
  73. package/src/component/_generated/component.ts +211 -1
  74. package/src/component/cardinality.ts +116 -0
  75. package/src/component/constants.ts +10 -0
  76. package/src/component/coverage.ts +25 -0
  77. package/src/component/errors.ts +2 -1
  78. package/src/component/http.ts +76 -6
  79. package/src/component/ingest.ts +387 -12
  80. package/src/component/live.ts +8 -3
  81. package/src/component/reports.ts +891 -86
  82. package/src/component/retention.ts +624 -88
  83. package/src/component/sanitize.ts +15 -4
  84. package/src/component/schema.ts +110 -0
  85. package/src/component/sites.ts +5 -1
  86. package/src/component/validators.ts +8 -0
@@ -0,0 +1,205 @@
1
+ import type { UserIdentity } from "convex/server";
2
+ import type { AnalyticsAuthorizationContext } from "./index.js";
3
+ export declare const FEDERATED_ANALYTICS_CLAIMS: Readonly<{
4
+ readonly connectionId: "rastro_connection_id";
5
+ readonly organizationId: "rastro_organization_id";
6
+ readonly permissions: "rastro_permissions";
7
+ }>;
8
+ export declare const FEDERATED_ANALYTICS_READ_PERMISSION = "analytics:read";
9
+ export declare const FEDERATED_ANALYTICS_ERROR_CODES: Readonly<{
10
+ readonly UNAUTHENTICATED: "FEDERATION_UNAUTHENTICATED";
11
+ readonly ISSUER_MISMATCH: "FEDERATION_ISSUER_MISMATCH";
12
+ readonly INVALID_CLAIMS: "FEDERATION_INVALID_CLAIMS";
13
+ readonly CONNECTION_DENIED: "FEDERATION_CONNECTION_DENIED";
14
+ readonly INVALID_SCOPE: "FEDERATION_INVALID_SCOPE";
15
+ readonly SITE_DENIED: "FEDERATION_SITE_DENIED";
16
+ }>;
17
+ export declare const FEDERATED_ANALYTICS_CONNECTOR_MANIFEST: Readonly<{
18
+ readonly protocol: "amage-rastro-analytics";
19
+ readonly protocolVersion: 1;
20
+ readonly moduleName: "rastroFederation";
21
+ readonly functions: Readonly<{
22
+ readonly manifest: "manifest";
23
+ readonly connectionStatus: "connectionStatus";
24
+ readonly listSites: "listSites";
25
+ readonly overview: "overview";
26
+ readonly liveVisitors: "liveVisitors";
27
+ readonly listSessions: "listSessions";
28
+ readonly sessionJourney: "sessionJourney";
29
+ readonly listConversions: "listConversions";
30
+ readonly visitorJourney: "visitorJourney";
31
+ readonly goalsReport: "goalsReport";
32
+ readonly funnelsReport: "funnelsReport";
33
+ readonly affiliatesReport: "affiliatesReport";
34
+ readonly dataCoverage: "dataCoverage";
35
+ }>;
36
+ readonly capabilities: readonly ["siteSummaries", "overview", "liveVisitors", "sessions", "sessionJourney", "conversions", "visitorJourney", "goals", "funnels", "affiliates", "dataCoverage"];
37
+ readonly limits: Readonly<{
38
+ readonly maxSitesPerRequest: 10;
39
+ readonly maxSitesPerConnection: 10;
40
+ readonly maxReportRangeDays: 366;
41
+ readonly maxLiveVisitors: 500;
42
+ readonly maxJourneyEvents: 500;
43
+ }>;
44
+ }>;
45
+ export type FederatedAnalyticsErrorCode = (typeof FEDERATED_ANALYTICS_ERROR_CODES)[keyof typeof FEDERATED_ANALYTICS_ERROR_CODES];
46
+ export type FederatedAnalyticsCapability = (typeof FEDERATED_ANALYTICS_CONNECTOR_MANIFEST.capabilities)[number];
47
+ export type FederatedAnalyticsManifest = ReturnType<typeof createFederatedAnalyticsManifest>;
48
+ export interface FederatedAnalyticsConnection {
49
+ connectionId: string;
50
+ organizationId: string;
51
+ siteIds: readonly string[];
52
+ revokedAt?: number;
53
+ }
54
+ export interface FederatedAnalyticsIdentity {
55
+ connectionId: string;
56
+ organizationId: string;
57
+ identity: UserIdentity;
58
+ }
59
+ export interface FederatedSiteSummary {
60
+ siteId: string;
61
+ name: string;
62
+ currency: string;
63
+ timezone: string | null;
64
+ cookieless: boolean;
65
+ }
66
+ export interface FederatedAnalyticsConnectionStatus {
67
+ status: "connected";
68
+ protocolVersion: 1;
69
+ capabilities: FederatedAnalyticsCapability[];
70
+ siteCount: number;
71
+ }
72
+ export type ResolveFederatedAnalyticsConnection = (ctx: AnalyticsAuthorizationContext, identity: FederatedAnalyticsIdentity) => FederatedAnalyticsConnection | null | Promise<FederatedAnalyticsConnection | null>;
73
+ export interface FederatedAnalyticsAuthorizerOptions {
74
+ issuer: string;
75
+ resolveConnection: ResolveFederatedAnalyticsConnection;
76
+ }
77
+ export declare const federatedAnalyticsManifestValidator: import("convex/values").VObject<{
78
+ capabilities: ("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney")[];
79
+ functions: {
80
+ affiliatesReport: "affiliatesReport";
81
+ connectionStatus: "connectionStatus";
82
+ dataCoverage: "dataCoverage";
83
+ funnelsReport: "funnelsReport";
84
+ goalsReport: "goalsReport";
85
+ listConversions: "listConversions";
86
+ listSessions: "listSessions";
87
+ listSites: "listSites";
88
+ liveVisitors: "liveVisitors";
89
+ manifest: "manifest";
90
+ overview: "overview";
91
+ sessionJourney: "sessionJourney";
92
+ visitorJourney: "visitorJourney";
93
+ };
94
+ limits: {
95
+ maxJourneyEvents: number;
96
+ maxLiveVisitors: number;
97
+ maxReportRangeDays: number;
98
+ maxSitesPerConnection: number;
99
+ maxSitesPerRequest: number;
100
+ };
101
+ moduleName: "rastroFederation";
102
+ protocol: "amage-rastro-analytics";
103
+ protocolVersion: 1;
104
+ }, {
105
+ protocol: import("convex/values").VLiteral<"amage-rastro-analytics", "required">;
106
+ protocolVersion: import("convex/values").VLiteral<1, "required">;
107
+ moduleName: import("convex/values").VLiteral<"rastroFederation", "required">;
108
+ functions: import("convex/values").VObject<{
109
+ affiliatesReport: "affiliatesReport";
110
+ connectionStatus: "connectionStatus";
111
+ dataCoverage: "dataCoverage";
112
+ funnelsReport: "funnelsReport";
113
+ goalsReport: "goalsReport";
114
+ listConversions: "listConversions";
115
+ listSessions: "listSessions";
116
+ listSites: "listSites";
117
+ liveVisitors: "liveVisitors";
118
+ manifest: "manifest";
119
+ overview: "overview";
120
+ sessionJourney: "sessionJourney";
121
+ visitorJourney: "visitorJourney";
122
+ }, {
123
+ manifest: import("convex/values").VLiteral<"manifest", "required">;
124
+ connectionStatus: import("convex/values").VLiteral<"connectionStatus", "required">;
125
+ listSites: import("convex/values").VLiteral<"listSites", "required">;
126
+ overview: import("convex/values").VLiteral<"overview", "required">;
127
+ liveVisitors: import("convex/values").VLiteral<"liveVisitors", "required">;
128
+ listSessions: import("convex/values").VLiteral<"listSessions", "required">;
129
+ sessionJourney: import("convex/values").VLiteral<"sessionJourney", "required">;
130
+ listConversions: import("convex/values").VLiteral<"listConversions", "required">;
131
+ visitorJourney: import("convex/values").VLiteral<"visitorJourney", "required">;
132
+ goalsReport: import("convex/values").VLiteral<"goalsReport", "required">;
133
+ funnelsReport: import("convex/values").VLiteral<"funnelsReport", "required">;
134
+ affiliatesReport: import("convex/values").VLiteral<"affiliatesReport", "required">;
135
+ dataCoverage: import("convex/values").VLiteral<"dataCoverage", "required">;
136
+ }, "required", "affiliatesReport" | "connectionStatus" | "dataCoverage" | "funnelsReport" | "goalsReport" | "listConversions" | "listSessions" | "listSites" | "liveVisitors" | "manifest" | "overview" | "sessionJourney" | "visitorJourney">;
137
+ capabilities: import("convex/values").VArray<("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney")[], import("convex/values").VUnion<"affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney", [import("convex/values").VLiteral<"siteSummaries", "required">, import("convex/values").VLiteral<"overview", "required">, import("convex/values").VLiteral<"liveVisitors", "required">, import("convex/values").VLiteral<"sessions", "required">, import("convex/values").VLiteral<"sessionJourney", "required">, import("convex/values").VLiteral<"conversions", "required">, import("convex/values").VLiteral<"visitorJourney", "required">, import("convex/values").VLiteral<"goals", "required">, import("convex/values").VLiteral<"funnels", "required">, import("convex/values").VLiteral<"affiliates", "required">, import("convex/values").VLiteral<"dataCoverage", "required">], "required", never>, "required">;
138
+ limits: import("convex/values").VObject<{
139
+ maxJourneyEvents: number;
140
+ maxLiveVisitors: number;
141
+ maxReportRangeDays: number;
142
+ maxSitesPerConnection: number;
143
+ maxSitesPerRequest: number;
144
+ }, {
145
+ maxSitesPerRequest: import("convex/values").VFloat64<number, "required">;
146
+ maxSitesPerConnection: import("convex/values").VFloat64<number, "required">;
147
+ maxReportRangeDays: import("convex/values").VFloat64<number, "required">;
148
+ maxLiveVisitors: import("convex/values").VFloat64<number, "required">;
149
+ maxJourneyEvents: import("convex/values").VFloat64<number, "required">;
150
+ }, "required", "maxJourneyEvents" | "maxLiveVisitors" | "maxReportRangeDays" | "maxSitesPerConnection" | "maxSitesPerRequest">;
151
+ }, "required", "capabilities" | "functions" | "functions.affiliatesReport" | "functions.connectionStatus" | "functions.dataCoverage" | "functions.funnelsReport" | "functions.goalsReport" | "functions.listConversions" | "functions.listSessions" | "functions.listSites" | "functions.liveVisitors" | "functions.manifest" | "functions.overview" | "functions.sessionJourney" | "functions.visitorJourney" | "limits" | "limits.maxJourneyEvents" | "limits.maxLiveVisitors" | "limits.maxReportRangeDays" | "limits.maxSitesPerConnection" | "limits.maxSitesPerRequest" | "moduleName" | "protocol" | "protocolVersion">;
152
+ export declare const federatedAnalyticsConnectionStatusValidator: import("convex/values").VObject<{
153
+ capabilities: ("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney")[];
154
+ protocolVersion: 1;
155
+ siteCount: number;
156
+ status: "connected";
157
+ }, {
158
+ status: import("convex/values").VLiteral<"connected", "required">;
159
+ protocolVersion: import("convex/values").VLiteral<1, "required">;
160
+ capabilities: import("convex/values").VArray<("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney")[], import("convex/values").VUnion<"affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney", [import("convex/values").VLiteral<"siteSummaries", "required">, import("convex/values").VLiteral<"overview", "required">, import("convex/values").VLiteral<"liveVisitors", "required">, import("convex/values").VLiteral<"sessions", "required">, import("convex/values").VLiteral<"sessionJourney", "required">, import("convex/values").VLiteral<"conversions", "required">, import("convex/values").VLiteral<"visitorJourney", "required">, import("convex/values").VLiteral<"goals", "required">, import("convex/values").VLiteral<"funnels", "required">, import("convex/values").VLiteral<"affiliates", "required">, import("convex/values").VLiteral<"dataCoverage", "required">], "required", never>, "required">;
161
+ siteCount: import("convex/values").VFloat64<number, "required">;
162
+ }, "required", "capabilities" | "protocolVersion" | "siteCount" | "status">;
163
+ export declare const federatedSiteSummaryValidator: import("convex/values").VObject<{
164
+ cookieless: boolean;
165
+ currency: string;
166
+ name: string;
167
+ siteId: string;
168
+ timezone: string | null;
169
+ }, {
170
+ siteId: import("convex/values").VString<string, "required">;
171
+ name: import("convex/values").VString<string, "required">;
172
+ currency: import("convex/values").VString<string, "required">;
173
+ timezone: import("convex/values").VUnion<string | null, [import("convex/values").VString<string, "required">, import("convex/values").VNull<null, "required">], "required", never>;
174
+ cookieless: import("convex/values").VBoolean<boolean, "required">;
175
+ }, "required", "cookieless" | "currency" | "name" | "siteId" | "timezone">;
176
+ export declare function createFederatedAnalyticsManifest(): {
177
+ protocol: "amage-rastro-analytics";
178
+ protocolVersion: 1;
179
+ moduleName: "rastroFederation";
180
+ functions: {
181
+ manifest: "manifest";
182
+ connectionStatus: "connectionStatus";
183
+ listSites: "listSites";
184
+ overview: "overview";
185
+ liveVisitors: "liveVisitors";
186
+ listSessions: "listSessions";
187
+ sessionJourney: "sessionJourney";
188
+ listConversions: "listConversions";
189
+ visitorJourney: "visitorJourney";
190
+ goalsReport: "goalsReport";
191
+ funnelsReport: "funnelsReport";
192
+ affiliatesReport: "affiliatesReport";
193
+ dataCoverage: "dataCoverage";
194
+ };
195
+ capabilities: ("affiliates" | "conversions" | "dataCoverage" | "funnels" | "goals" | "liveVisitors" | "overview" | "sessionJourney" | "sessions" | "siteSummaries" | "visitorJourney")[];
196
+ limits: {
197
+ maxSitesPerRequest: 10;
198
+ maxSitesPerConnection: 10;
199
+ maxReportRangeDays: 366;
200
+ maxLiveVisitors: 500;
201
+ maxJourneyEvents: 500;
202
+ };
203
+ };
204
+ export declare function createFederatedAnalyticsConnectionAuthorizer(options: FederatedAnalyticsAuthorizerOptions): (ctx: AnalyticsAuthorizationContext, requestedSiteIds?: readonly string[]) => Promise<FederatedAnalyticsConnection>;
205
+ //# sourceMappingURL=federation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"federation.d.ts","sourceRoot":"","sources":["../../src/client/federation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAQlD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAEhE,eAAO,MAAM,0BAA0B;2BACvB,sBAAsB;6BACpB,wBAAwB;0BAC3B,oBAAoB;EACxB,CAAC;AAEZ,eAAO,MAAM,mCAAmC,mBAAmB,CAAC;AAEpE,eAAO,MAAM,+BAA+B;8BACzB,4BAA4B;8BAC5B,4BAA4B;6BAC7B,2BAA2B;gCACxB,8BAA8B;4BAClC,0BAA0B;0BAC5B,wBAAwB;EAC5B,CAAC;AAuCZ,eAAO,MAAM,sCAAsC;uBACvC,wBAAwB;8BACjB,CAAC;yBACN,kBAAkB;;2BAtCpB,UAAU;mCACF,kBAAkB;4BACzB,WAAW;2BACZ,UAAU;+BACN,cAAc;+BACd,cAAc;iCACZ,gBAAgB;kCACf,iBAAiB;iCAClB,gBAAgB;8BACnB,aAAa;gCACX,eAAe;mCACZ,kBAAkB;+BACtB,cAAc;;;;;;;;;;EA8BnB,CAAC;AAKZ,MAAM,MAAM,2BAA2B,GACrC,CAAC,OAAO,+BAA+B,CAAC,CAAC,MAAM,OAAO,+BAA+B,CAAC,CAAC;AACzF,MAAM,MAAM,4BAA4B,GACtC,CAAC,OAAO,sCAAsC,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AACvE,MAAM,MAAM,0BAA0B,GAAG,UAAU,CACjD,OAAO,gCAAgC,CACxC,CAAC;AAEF,MAAM,WAAW,4BAA4B;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kCAAkC;IACjD,MAAM,EAAE,WAAW,CAAC;IACpB,eAAe,EAAE,CAAC,CAAC;IACnB,YAAY,EAAE,4BAA4B,EAAE,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,mCAAmC,GAAG,CAChD,GAAG,EAAE,6BAA6B,EAClC,QAAQ,EAAE,0BAA0B,KAElC,4BAA4B,GAC5B,IAAI,GACJ,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAAC;AAEjD,MAAM,WAAW,mCAAmC;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,mCAAmC,CAAC;CACxD;AAgBD,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8lBA6B9C,CAAC;AAEH,eAAO,MAAM,2CAA2C;;;;;;;;;;2EAKtD,CAAC;AAEH,eAAO,MAAM,6BAA6B;;;;;;;;;;;;0EAMxC,CAAC;AAEH,wBAAgB,gCAAgC;cAxHpC,wBAAwB;qBACjB,CAAC;gBACN,kBAAkB;;kBAtCpB,UAAU;0BACF,kBAAkB;mBACzB,WAAW;kBACZ,UAAU;sBACN,cAAc;sBACd,cAAc;wBACZ,gBAAgB;yBACf,iBAAiB;wBAClB,gBAAgB;qBACnB,aAAa;uBACX,eAAe;0BACZ,kBAAkB;sBACtB,cAAc;;;;;;;;;;EAuJ7B;AAED,wBAAgB,4CAA4C,CAC1D,OAAO,EAAE,mCAAmC,SAUrC,6BAA6B,qBACf,SAAS,MAAM,EAAE,KACnC,OAAO,CAAC,4BAA4B,CAAC,CA0EzC"}
@@ -0,0 +1,179 @@
1
+ import { ConvexError, v } from "convex/values";
2
+ import { MAX_JOURNEY_EVENTS, MAX_LIVE_VISITORS, MAX_REPORT_RANGE_DAYS, MAX_REPORT_SITES, } from "../component/constants.js";
3
+ export const FEDERATED_ANALYTICS_CLAIMS = Object.freeze({
4
+ connectionId: "rastro_connection_id",
5
+ organizationId: "rastro_organization_id",
6
+ permissions: "rastro_permissions",
7
+ });
8
+ export const FEDERATED_ANALYTICS_READ_PERMISSION = "analytics:read";
9
+ export const FEDERATED_ANALYTICS_ERROR_CODES = Object.freeze({
10
+ UNAUTHENTICATED: "FEDERATION_UNAUTHENTICATED",
11
+ ISSUER_MISMATCH: "FEDERATION_ISSUER_MISMATCH",
12
+ INVALID_CLAIMS: "FEDERATION_INVALID_CLAIMS",
13
+ CONNECTION_DENIED: "FEDERATION_CONNECTION_DENIED",
14
+ INVALID_SCOPE: "FEDERATION_INVALID_SCOPE",
15
+ SITE_DENIED: "FEDERATION_SITE_DENIED",
16
+ });
17
+ const MAX_CONNECTION_SITE_IDS = MAX_REPORT_SITES;
18
+ const FEDERATED_ANALYTICS_FUNCTION_NAMES = Object.freeze({
19
+ manifest: "manifest",
20
+ connectionStatus: "connectionStatus",
21
+ listSites: "listSites",
22
+ overview: "overview",
23
+ liveVisitors: "liveVisitors",
24
+ listSessions: "listSessions",
25
+ sessionJourney: "sessionJourney",
26
+ listConversions: "listConversions",
27
+ visitorJourney: "visitorJourney",
28
+ goalsReport: "goalsReport",
29
+ funnelsReport: "funnelsReport",
30
+ affiliatesReport: "affiliatesReport",
31
+ dataCoverage: "dataCoverage",
32
+ });
33
+ const FEDERATED_ANALYTICS_CAPABILITIES = Object.freeze([
34
+ "siteSummaries",
35
+ "overview",
36
+ "liveVisitors",
37
+ "sessions",
38
+ "sessionJourney",
39
+ "conversions",
40
+ "visitorJourney",
41
+ "goals",
42
+ "funnels",
43
+ "affiliates",
44
+ "dataCoverage",
45
+ ]);
46
+ const FEDERATED_ANALYTICS_LIMITS = Object.freeze({
47
+ maxSitesPerRequest: MAX_REPORT_SITES,
48
+ maxSitesPerConnection: MAX_CONNECTION_SITE_IDS,
49
+ maxReportRangeDays: MAX_REPORT_RANGE_DAYS,
50
+ maxLiveVisitors: MAX_LIVE_VISITORS,
51
+ maxJourneyEvents: MAX_JOURNEY_EVENTS,
52
+ });
53
+ export const FEDERATED_ANALYTICS_CONNECTOR_MANIFEST = Object.freeze({
54
+ protocol: "amage-rastro-analytics",
55
+ protocolVersion: 1,
56
+ moduleName: "rastroFederation",
57
+ functions: FEDERATED_ANALYTICS_FUNCTION_NAMES,
58
+ capabilities: FEDERATED_ANALYTICS_CAPABILITIES,
59
+ limits: FEDERATED_ANALYTICS_LIMITS,
60
+ });
61
+ const MAX_CLAIM_LENGTH = 128;
62
+ const MAX_PERMISSIONS = 16;
63
+ const federatedAnalyticsCapabilityValidator = v.union(v.literal("siteSummaries"), v.literal("overview"), v.literal("liveVisitors"), v.literal("sessions"), v.literal("sessionJourney"), v.literal("conversions"), v.literal("visitorJourney"), v.literal("goals"), v.literal("funnels"), v.literal("affiliates"), v.literal("dataCoverage"));
64
+ export const federatedAnalyticsManifestValidator = v.object({
65
+ protocol: v.literal(FEDERATED_ANALYTICS_CONNECTOR_MANIFEST.protocol),
66
+ protocolVersion: v.literal(FEDERATED_ANALYTICS_CONNECTOR_MANIFEST.protocolVersion),
67
+ moduleName: v.literal(FEDERATED_ANALYTICS_CONNECTOR_MANIFEST.moduleName),
68
+ functions: v.object({
69
+ manifest: v.literal("manifest"),
70
+ connectionStatus: v.literal("connectionStatus"),
71
+ listSites: v.literal("listSites"),
72
+ overview: v.literal("overview"),
73
+ liveVisitors: v.literal("liveVisitors"),
74
+ listSessions: v.literal("listSessions"),
75
+ sessionJourney: v.literal("sessionJourney"),
76
+ listConversions: v.literal("listConversions"),
77
+ visitorJourney: v.literal("visitorJourney"),
78
+ goalsReport: v.literal("goalsReport"),
79
+ funnelsReport: v.literal("funnelsReport"),
80
+ affiliatesReport: v.literal("affiliatesReport"),
81
+ dataCoverage: v.literal("dataCoverage"),
82
+ }),
83
+ capabilities: v.array(federatedAnalyticsCapabilityValidator),
84
+ limits: v.object({
85
+ maxSitesPerRequest: v.number(),
86
+ maxSitesPerConnection: v.number(),
87
+ maxReportRangeDays: v.number(),
88
+ maxLiveVisitors: v.number(),
89
+ maxJourneyEvents: v.number(),
90
+ }),
91
+ });
92
+ export const federatedAnalyticsConnectionStatusValidator = v.object({
93
+ status: v.literal("connected"),
94
+ protocolVersion: v.literal(1),
95
+ capabilities: v.array(federatedAnalyticsCapabilityValidator),
96
+ siteCount: v.number(),
97
+ });
98
+ export const federatedSiteSummaryValidator = v.object({
99
+ siteId: v.string(),
100
+ name: v.string(),
101
+ currency: v.string(),
102
+ timezone: v.union(v.string(), v.null()),
103
+ cookieless: v.boolean(),
104
+ });
105
+ export function createFederatedAnalyticsManifest() {
106
+ return {
107
+ ...FEDERATED_ANALYTICS_CONNECTOR_MANIFEST,
108
+ functions: { ...FEDERATED_ANALYTICS_CONNECTOR_MANIFEST.functions },
109
+ capabilities: [...FEDERATED_ANALYTICS_CONNECTOR_MANIFEST.capabilities],
110
+ limits: { ...FEDERATED_ANALYTICS_CONNECTOR_MANIFEST.limits },
111
+ };
112
+ }
113
+ export function createFederatedAnalyticsConnectionAuthorizer(options) {
114
+ if (!isBoundedClaim(options?.issuer)) {
115
+ throw new Error("Federated analytics issuer must be a non-empty string");
116
+ }
117
+ if (typeof options.resolveConnection !== "function") {
118
+ throw new Error("Federated analytics connection resolver is required");
119
+ }
120
+ return async (ctx, requestedSiteIds) => {
121
+ const identity = await ctx.auth.getUserIdentity();
122
+ if (!identity) {
123
+ fail(FEDERATED_ANALYTICS_ERROR_CODES.UNAUTHENTICATED, "Federated analytics authentication is required");
124
+ }
125
+ if (identity.issuer !== options.issuer) {
126
+ fail(FEDERATED_ANALYTICS_ERROR_CODES.ISSUER_MISMATCH, "Federated analytics issuer is not trusted");
127
+ }
128
+ const connectionId = identity[FEDERATED_ANALYTICS_CLAIMS.connectionId];
129
+ const organizationId = identity[FEDERATED_ANALYTICS_CLAIMS.organizationId];
130
+ const permissions = identity[FEDERATED_ANALYTICS_CLAIMS.permissions];
131
+ if (!isBoundedClaim(connectionId) ||
132
+ !isBoundedClaim(organizationId) ||
133
+ !isStringArray(permissions, MAX_PERMISSIONS) ||
134
+ !permissions.includes(FEDERATED_ANALYTICS_READ_PERMISSION)) {
135
+ fail(FEDERATED_ANALYTICS_ERROR_CODES.INVALID_CLAIMS, "Federated analytics claims are invalid");
136
+ }
137
+ const connection = await options.resolveConnection(ctx, {
138
+ connectionId,
139
+ organizationId,
140
+ identity,
141
+ });
142
+ if (!connection ||
143
+ connection.revokedAt !== undefined ||
144
+ connection.connectionId !== connectionId ||
145
+ connection.organizationId !== organizationId ||
146
+ !isStringArray(connection.siteIds, MAX_CONNECTION_SITE_IDS) ||
147
+ connection.siteIds.length === 0 ||
148
+ new Set(connection.siteIds).size !== connection.siteIds.length) {
149
+ fail(FEDERATED_ANALYTICS_ERROR_CODES.CONNECTION_DENIED, "Federated analytics connection is not active");
150
+ }
151
+ if (requestedSiteIds !== undefined) {
152
+ if (requestedSiteIds.length === 0 ||
153
+ requestedSiteIds.length > MAX_REPORT_SITES ||
154
+ new Set(requestedSiteIds).size !== requestedSiteIds.length ||
155
+ requestedSiteIds.some((siteId) => !isBoundedClaim(siteId))) {
156
+ fail(FEDERATED_ANALYTICS_ERROR_CODES.INVALID_SCOPE, "Federated analytics site scope is invalid");
157
+ }
158
+ const allowedSiteIds = new Set(connection.siteIds);
159
+ if (requestedSiteIds.some((siteId) => !allowedSiteIds.has(siteId))) {
160
+ fail(FEDERATED_ANALYTICS_ERROR_CODES.SITE_DENIED, "Federated analytics site is not authorized");
161
+ }
162
+ }
163
+ return connection;
164
+ };
165
+ }
166
+ function isBoundedClaim(value) {
167
+ return (typeof value === "string" &&
168
+ value.length > 0 &&
169
+ value.length <= MAX_CLAIM_LENGTH);
170
+ }
171
+ function isStringArray(value, maximumLength) {
172
+ return (Array.isArray(value) &&
173
+ value.length <= maximumLength &&
174
+ value.every(isBoundedClaim));
175
+ }
176
+ function fail(code, message) {
177
+ throw new ConvexError({ code, message });
178
+ }
179
+ //# sourceMappingURL=federation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"federation.js","sourceRoot":"","sources":["../../src/client/federation.ts"],"names":[],"mappings":"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"}