@happyvertical/analytics 0.74.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT.md +33 -0
- package/LICENSE +7 -0
- package/dist/chunks/ga4-6gyDPZRn.js +863 -0
- package/dist/chunks/ga4-6gyDPZRn.js.map +1 -0
- package/dist/chunks/matomo-Ds_oRmZ6.js +1043 -0
- package/dist/chunks/matomo-Ds_oRmZ6.js.map +1 -0
- package/dist/chunks/plausible-BxpNa6qF.js +479 -0
- package/dist/chunks/plausible-BxpNa6qF.js.map +1 -0
- package/dist/cli/claude-context.d.ts +3 -0
- package/dist/cli/claude-context.d.ts.map +1 -0
- package/dist/cli/claude-context.js +21 -0
- package/dist/cli/claude-context.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +135 -0
- package/dist/index.js.map +1 -0
- package/dist/shared/factory.d.ts +48 -0
- package/dist/shared/factory.d.ts.map +1 -0
- package/dist/shared/providers/ga4.d.ts +68 -0
- package/dist/shared/providers/ga4.d.ts.map +1 -0
- package/dist/shared/providers/matomo-admin.d.ts +56 -0
- package/dist/shared/providers/matomo-admin.d.ts.map +1 -0
- package/dist/shared/providers/matomo.d.ts +49 -0
- package/dist/shared/providers/matomo.d.ts.map +1 -0
- package/dist/shared/providers/plausible.d.ts +50 -0
- package/dist/shared/providers/plausible.d.ts.map +1 -0
- package/dist/shared/types.d.ts +1235 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/metadata.json +30 -0
- package/package.json +57 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plausible-BxpNa6qF.js","sources":["../../src/shared/providers/plausible.ts"],"sourcesContent":["/**\n * Plausible Analytics provider implementation\n *\n * Uses three APIs:\n * - Sites API: Site management\n * - Stats API v2: Reports and analytics queries\n * - Events API: Server-side event tracking\n */\n\nimport type {\n AnalyticsCapabilities,\n AnalyticsInterface,\n ConfigOptions,\n CreateDataStreamOptions,\n CreatePropertyOptions,\n CustomDimension,\n CustomDimensionOptions,\n CustomMetric,\n CustomMetricOptions,\n DataStream,\n DimensionMetadata,\n KeyEvent,\n KeyEventOptions,\n ListPropertiesOptions,\n MetricMetadata,\n PageviewEvent,\n PlausibleOptions,\n Property,\n RealtimeReportOptions,\n ReportOptions,\n ReportResult,\n SnippetOptions,\n TrackEvent,\n TrackingSnippet,\n UpdatePropertyOptions,\n} from '../types.js';\nimport {\n AnalyticsError,\n AuthenticationError,\n NotSupportedError,\n PropertyNotFoundError,\n RateLimitError,\n} from '../types.js';\n\n/**\n * Default Plausible base URL\n */\nconst DEFAULT_BASE_URL = 'https://plausible.io';\n\n/**\n * Plausible Analytics provider\n */\nexport class PlausibleProvider implements AnalyticsInterface {\n private options: PlausibleOptions;\n private baseUrl: string;\n\n constructor(options: PlausibleOptions) {\n this.options = {\n timeout: 30000,\n maxRetries: 3,\n baseUrl: DEFAULT_BASE_URL,\n ...options,\n };\n this.baseUrl = this.options.baseUrl || DEFAULT_BASE_URL;\n }\n\n /**\n * Make an authenticated API request\n */\n private async request<T>(\n endpoint: string,\n options: {\n method?: string;\n body?: unknown;\n headers?: Record<string, string>;\n } = {},\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n const method = options.method || 'GET';\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n Authorization: `Bearer ${this.options.apiKey}`,\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new AuthenticationError('plausible');\n }\n if (response.status === 404) {\n throw new PropertyNotFoundError(endpoint, 'plausible');\n }\n if (response.status === 429) {\n const retryAfter = response.headers.get('Retry-After');\n throw new RateLimitError(\n 'plausible',\n retryAfter ? Number.parseInt(retryAfter, 10) : undefined,\n );\n }\n\n const errorText = await response.text();\n throw new AnalyticsError(\n `Plausible API error: ${response.status} - ${errorText}`,\n 'API_ERROR',\n 'plausible',\n );\n }\n\n // Handle empty responses\n const text = await response.text();\n if (!text) {\n return {} as T;\n }\n\n return JSON.parse(text) as T;\n } catch (error) {\n if (error instanceof AnalyticsError) {\n throw error;\n }\n throw new AnalyticsError(\n `Network error: ${(error as Error).message}`,\n 'NETWORK_ERROR',\n 'plausible',\n );\n }\n }\n\n // ===========================================================================\n // Property Management (Sites API)\n // ===========================================================================\n\n async createProperty(options: CreatePropertyOptions): Promise<Property> {\n // Plausible uses domain as the site ID\n const domain = options.displayName;\n\n interface PlausibleSite {\n domain: string;\n timezone?: string;\n }\n\n const site = await this.request<PlausibleSite>('/api/v1/sites', {\n method: 'POST',\n body: {\n domain,\n timezone: options.timeZone || 'Etc/UTC',\n },\n });\n\n return {\n id: site.domain,\n name: site.domain,\n displayName: site.domain,\n createTime: new Date().toISOString(),\n timeZone: site.timezone,\n };\n }\n\n async listProperties(_options?: ListPropertiesOptions): Promise<Property[]> {\n // Plausible doesn't have a list sites endpoint in the public API\n // This will need to be implemented when they add it\n throw new NotSupportedError('listProperties', 'plausible');\n }\n\n async getProperty(propertyId: string): Promise<Property> {\n // Plausible doesn't have a get site endpoint\n // Return a minimal property object\n return {\n id: propertyId,\n name: propertyId,\n displayName: propertyId,\n createTime: '',\n };\n }\n\n async updateProperty(\n _propertyId: string,\n _data: UpdatePropertyOptions,\n ): Promise<Property> {\n // Plausible doesn't support updating site settings via API\n throw new NotSupportedError('updateProperty', 'plausible');\n }\n\n async deleteProperty(propertyId: string): Promise<void> {\n await this.request(`/api/v1/sites/${propertyId}`, {\n method: 'DELETE',\n });\n }\n\n // ===========================================================================\n // Data Streams (Not supported by Plausible)\n // ===========================================================================\n\n async getDataStreams(_propertyId: string): Promise<DataStream[]> {\n throw new NotSupportedError('getDataStreams', 'plausible');\n }\n\n async createDataStream(\n _propertyId: string,\n _options: CreateDataStreamOptions,\n ): Promise<DataStream> {\n throw new NotSupportedError('createDataStream', 'plausible');\n }\n\n async deleteDataStream(\n _propertyId: string,\n _streamId: string,\n ): Promise<void> {\n throw new NotSupportedError('deleteDataStream', 'plausible');\n }\n\n // ===========================================================================\n // Custom Definitions (Not supported by Plausible via API)\n // ===========================================================================\n\n async getCustomDimensions(_propertyId: string): Promise<CustomDimension[]> {\n throw new NotSupportedError('getCustomDimensions', 'plausible');\n }\n\n async createCustomDimension(\n _propertyId: string,\n _options: CustomDimensionOptions,\n ): Promise<CustomDimension> {\n throw new NotSupportedError('createCustomDimension', 'plausible');\n }\n\n async archiveCustomDimension(\n _propertyId: string,\n _dimensionId: string,\n ): Promise<void> {\n throw new NotSupportedError('archiveCustomDimension', 'plausible');\n }\n\n async getCustomMetrics(_propertyId: string): Promise<CustomMetric[]> {\n throw new NotSupportedError('getCustomMetrics', 'plausible');\n }\n\n async createCustomMetric(\n _propertyId: string,\n _options: CustomMetricOptions,\n ): Promise<CustomMetric> {\n throw new NotSupportedError('createCustomMetric', 'plausible');\n }\n\n async archiveCustomMetric(\n _propertyId: string,\n _metricId: string,\n ): Promise<void> {\n throw new NotSupportedError('archiveCustomMetric', 'plausible');\n }\n\n // ===========================================================================\n // Key Events (Goals in Plausible - limited API support)\n // ===========================================================================\n\n async getKeyEvents(_propertyId: string): Promise<KeyEvent[]> {\n throw new NotSupportedError('getKeyEvents', 'plausible');\n }\n\n async createKeyEvent(\n propertyId: string,\n options: KeyEventOptions,\n ): Promise<KeyEvent> {\n // Plausible supports creating goals via API\n interface PlausibleGoal {\n id: number;\n display_name: string;\n goal_type: string;\n }\n\n const goal = await this.request<PlausibleGoal>(\n `/api/v1/sites/${propertyId}/goals`,\n {\n method: 'PUT',\n body: {\n goal_type: 'event',\n event_name: options.eventName,\n },\n },\n );\n\n return {\n id: String(goal.id),\n name: goal.display_name,\n eventName: options.eventName,\n createTime: new Date().toISOString(),\n };\n }\n\n async deleteKeyEvent(propertyId: string, eventId: string): Promise<void> {\n await this.request(`/api/v1/sites/${propertyId}/goals/${eventId}`, {\n method: 'DELETE',\n });\n }\n\n // ===========================================================================\n // Reporting (Stats API v2)\n // ===========================================================================\n\n async runReport(\n propertyId: string,\n options: ReportOptions,\n ): Promise<ReportResult> {\n const siteId = propertyId;\n const dateRange = options.dateRanges[0];\n\n // Convert to Plausible Stats API v2 format\n interface PlausibleQueryRequest {\n site_id: string;\n metrics: string[];\n date_range: [string, string];\n dimensions?: string[];\n filters?: Array<[string, string, string[]]>;\n order_by?: Array<[string, string]>;\n pagination?: {\n limit?: number;\n offset?: number;\n };\n }\n\n const queryBody: PlausibleQueryRequest = {\n site_id: siteId,\n metrics: options.metrics.map((m) => this.mapMetricName(m.name)),\n date_range: [dateRange.startDate, dateRange.endDate],\n };\n\n if (options.dimensions) {\n queryBody.dimensions = options.dimensions.map((d) =>\n this.mapDimensionName(d.name),\n );\n }\n\n if (options.orderBys) {\n queryBody.order_by = options.orderBys.map((o) => [\n o.metric?.metricName || o.dimension?.dimensionName || '',\n o.desc ? 'desc' : 'asc',\n ]);\n }\n\n if (options.limit || options.offset) {\n queryBody.pagination = {\n limit: options.limit,\n offset: options.offset,\n };\n }\n\n interface PlausibleQueryResponse {\n results: Array<{\n dimensions: string[];\n metrics: number[];\n }>;\n meta: {\n imports_included?: boolean;\n time_labels?: string[];\n total_rows?: number;\n };\n query: PlausibleQueryRequest;\n }\n\n const response = await this.request<PlausibleQueryResponse>(\n '/api/v2/query',\n {\n method: 'POST',\n body: queryBody,\n },\n );\n\n // Convert Plausible response to our format\n return {\n dimensionHeaders: (options.dimensions || []).map((d) => ({\n name: d.name,\n })),\n metricHeaders: options.metrics.map((m) => ({\n name: m.name,\n type: 'TYPE_INTEGER',\n })),\n rows: response.results.map((r) => ({\n dimensionValues: r.dimensions.map((v) => ({ value: String(v) })),\n metricValues: r.metrics.map((v) => ({ value: String(v) })),\n })),\n rowCount: response.meta.total_rows,\n };\n }\n\n async runRealtimeReport(\n propertyId: string,\n _options?: RealtimeReportOptions,\n ): Promise<ReportResult> {\n // Use the legacy v1 realtime endpoint\n interface PlausibleRealtimeResponse {\n visitors: number;\n }\n\n const response = await this.request<PlausibleRealtimeResponse>(\n `/api/v1/stats/realtime/visitors?site_id=${propertyId}`,\n );\n\n return {\n dimensionHeaders: [],\n metricHeaders: [{ name: 'activeUsers', type: 'TYPE_INTEGER' }],\n rows: [\n {\n dimensionValues: [],\n metricValues: [{ value: String(response.visitors) }],\n },\n ],\n };\n }\n\n async getMetrics(_propertyId: string): Promise<MetricMetadata[]> {\n // Plausible has a fixed set of metrics\n return [\n {\n apiName: 'visitors',\n uiName: 'Visitors',\n description: 'Unique visitors',\n type: 'TYPE_INTEGER',\n },\n {\n apiName: 'pageviews',\n uiName: 'Pageviews',\n description: 'Total page views',\n type: 'TYPE_INTEGER',\n },\n {\n apiName: 'bounce_rate',\n uiName: 'Bounce Rate',\n description: 'Percentage of single-page sessions',\n type: 'TYPE_FLOAT',\n },\n {\n apiName: 'visit_duration',\n uiName: 'Visit Duration',\n description: 'Average visit duration in seconds',\n type: 'TYPE_SECONDS',\n },\n {\n apiName: 'events',\n uiName: 'Events',\n description: 'Total events',\n type: 'TYPE_INTEGER',\n },\n {\n apiName: 'visits',\n uiName: 'Visits',\n description: 'Total visits (sessions)',\n type: 'TYPE_INTEGER',\n },\n {\n apiName: 'views_per_visit',\n uiName: 'Views per Visit',\n description: 'Average page views per visit',\n type: 'TYPE_FLOAT',\n },\n ];\n }\n\n async getDimensions(_propertyId: string): Promise<DimensionMetadata[]> {\n // Plausible has a fixed set of dimensions\n return [\n {\n apiName: 'event:page',\n uiName: 'Page',\n description: 'Page path',\n },\n {\n apiName: 'visit:source',\n uiName: 'Source',\n description: 'Traffic source',\n },\n {\n apiName: 'visit:referrer',\n uiName: 'Referrer',\n description: 'Referrer URL',\n },\n {\n apiName: 'visit:utm_source',\n uiName: 'UTM Source',\n description: 'UTM source parameter',\n },\n {\n apiName: 'visit:utm_medium',\n uiName: 'UTM Medium',\n description: 'UTM medium parameter',\n },\n {\n apiName: 'visit:utm_campaign',\n uiName: 'UTM Campaign',\n description: 'UTM campaign parameter',\n },\n {\n apiName: 'visit:device',\n uiName: 'Device',\n description: 'Device type',\n },\n {\n apiName: 'visit:browser',\n uiName: 'Browser',\n description: 'Browser name',\n },\n {\n apiName: 'visit:os',\n uiName: 'OS',\n description: 'Operating system',\n },\n {\n apiName: 'visit:country',\n uiName: 'Country',\n description: 'Country name',\n },\n {\n apiName: 'visit:city',\n uiName: 'City',\n description: 'City name',\n },\n ];\n }\n\n /**\n * Map GA4-style metric names to Plausible format\n */\n private mapMetricName(name: string): string {\n const mapping: Record<string, string> = {\n activeUsers: 'visitors',\n users: 'visitors',\n sessions: 'visits',\n pageviews: 'pageviews',\n bounceRate: 'bounce_rate',\n avgSessionDuration: 'visit_duration',\n events: 'events',\n };\n return mapping[name] || name;\n }\n\n /**\n * Map GA4-style dimension names to Plausible format\n */\n private mapDimensionName(name: string): string {\n const mapping: Record<string, string> = {\n pagePath: 'event:page',\n page: 'event:page',\n source: 'visit:source',\n medium: 'visit:utm_medium',\n campaign: 'visit:utm_campaign',\n country: 'visit:country',\n city: 'visit:city',\n deviceCategory: 'visit:device',\n browser: 'visit:browser',\n operatingSystem: 'visit:os',\n };\n return mapping[name] || name;\n }\n\n // ===========================================================================\n // Event Tracking (Events API)\n // ===========================================================================\n\n async track(event: TrackEvent): Promise<void> {\n const siteId = this.options.defaultSiteId;\n\n if (!siteId) {\n throw new AnalyticsError(\n 'Default site ID is required for server-side tracking',\n 'MISSING_SITE_ID',\n 'plausible',\n );\n }\n\n // Plausible Events API requires specific headers\n await this.request('/api/event', {\n method: 'POST',\n headers: {\n 'User-Agent': 'Mozilla/5.0 (compatible; PlausibleBot/1.0)',\n 'X-Forwarded-For': '127.0.0.1', // Will be overwritten by actual IP in production\n },\n body: {\n name: event.name,\n url: `https://${siteId}`,\n domain: siteId,\n props: event.params,\n },\n });\n }\n\n async trackPageview(pageview: PageviewEvent): Promise<void> {\n const siteId = this.options.defaultSiteId;\n\n if (!siteId) {\n throw new AnalyticsError(\n 'Default site ID is required for server-side tracking',\n 'MISSING_SITE_ID',\n 'plausible',\n );\n }\n\n await this.request('/api/event', {\n method: 'POST',\n headers: {\n 'User-Agent': 'Mozilla/5.0 (compatible; PlausibleBot/1.0)',\n 'X-Forwarded-For': '127.0.0.1',\n },\n body: {\n name: 'pageview',\n url: pageview.pageLocation || `https://${siteId}${pageview.pagePath}`,\n domain: siteId,\n props: pageview.params,\n },\n });\n }\n\n async trackBatch(events: TrackEvent[]): Promise<void> {\n // Plausible doesn't have a batch API, so we send events sequentially\n for (const event of events) {\n await this.track(event);\n }\n }\n\n async identify(\n _userId: string,\n _traits?: Record<string, unknown>,\n ): Promise<void> {\n // Plausible is privacy-focused and doesn't support user identification\n throw new NotSupportedError('identify', 'plausible');\n }\n\n // ===========================================================================\n // Client-Side Helpers\n // ===========================================================================\n\n generateTrackingSnippet(\n propertyId: string,\n _options?: SnippetOptions,\n ): TrackingSnippet {\n const domain = propertyId;\n const scriptUrl = `${this.baseUrl}/js/script.js`;\n\n // Plausible supports various script extensions\n const _scriptPath = 'script.js';\n const _extensions: string[] = [];\n\n // Note: These would need to be configured based on Plausible plan features\n // For now, using the basic script\n\n const html = `<script defer data-domain=\"${domain}\" src=\"${scriptUrl}\"></script>`;\n\n return {\n html,\n config: {\n domain,\n scriptUrl,\n },\n scripts: [scriptUrl],\n };\n }\n\n generateConfig(\n propertyId: string,\n _options?: ConfigOptions,\n ): Record<string, unknown> {\n return {\n domain: propertyId,\n apiHost: this.baseUrl,\n };\n }\n\n // ===========================================================================\n // Provider Info\n // ===========================================================================\n\n async getCapabilities(): Promise<AnalyticsCapabilities> {\n return {\n propertyManagement: true, // Limited - create and delete only\n dataStreams: false,\n customDimensions: false, // Via UI only\n customMetrics: false,\n keyEvents: true, // Goals\n reporting: true,\n realtimeReporting: true,\n serverSideTracking: true,\n clientSideSnippet: true,\n userIdentification: false, // Privacy-focused\n batchTracking: false, // No batch API\n };\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-context.d.ts","sourceRoot":"","sources":["../../src/cli/claude-context.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, mkdirSync, copyFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
const Dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const pkgRoot = join(Dirname, "../..");
|
|
7
|
+
const targetDir = join(process.cwd(), ".claude");
|
|
8
|
+
if (!existsSync(targetDir)) {
|
|
9
|
+
mkdirSync(targetDir, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
const pkgName = "analytics";
|
|
12
|
+
const agentMdSrc = existsSync(join(pkgRoot, "AGENT.md")) ? join(pkgRoot, "AGENT.md") : join(pkgRoot, "CLAUDE.md");
|
|
13
|
+
const metaSrc = existsSync(join(pkgRoot, "metadata.json")) ? join(pkgRoot, "metadata.json") : join(pkgRoot, ".claude-meta.json");
|
|
14
|
+
if (existsSync(agentMdSrc)) {
|
|
15
|
+
copyFileSync(agentMdSrc, join(targetDir, `have-${pkgName}.md`));
|
|
16
|
+
}
|
|
17
|
+
if (existsSync(metaSrc)) {
|
|
18
|
+
copyFileSync(metaSrc, join(targetDir, `have-${pkgName}.meta.json`));
|
|
19
|
+
}
|
|
20
|
+
console.log(`✓ Installed @happyvertical/${pkgName} context to .claude/`);
|
|
21
|
+
//# sourceMappingURL=claude-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-context.js","sources":["../../src/cli/claude-context.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI script to install agent context for @happyvertical/analytics\n * Run the published context installer binary for this package.\n */\nimport { copyFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst Dirname = dirname(fileURLToPath(import.meta.url));\nconst pkgRoot = join(Dirname, '../..');\nconst targetDir = join(process.cwd(), '.claude');\n\nif (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n}\n\nconst pkgName = 'analytics';\nconst agentMdSrc = existsSync(join(pkgRoot, 'AGENT.md'))\n ? join(pkgRoot, 'AGENT.md')\n : join(pkgRoot, 'CLAUDE.md');\nconst metaSrc = existsSync(join(pkgRoot, 'metadata.json'))\n ? join(pkgRoot, 'metadata.json')\n : join(pkgRoot, '.claude-meta.json');\n\nif (existsSync(agentMdSrc)) {\n copyFileSync(agentMdSrc, join(targetDir, `have-${pkgName}.md`));\n}\n\nif (existsSync(metaSrc)) {\n copyFileSync(metaSrc, join(targetDir, `have-${pkgName}.meta.json`));\n}\n\nconsole.log(`✓ Installed @happyvertical/${pkgName} context to .claude/`);\n"],"names":[],"mappings":";;;;AASA,MAAM,UAAU,QAAQ,cAAc,YAAY,GAAG,CAAC;AACtD,MAAM,UAAU,KAAK,SAAS,OAAO;AACrC,MAAM,YAAY,KAAK,QAAQ,IAAA,GAAO,SAAS;AAE/C,IAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,YAAU,WAAW,EAAE,WAAW,KAAA,CAAM;AAC1C;AAEA,MAAM,UAAU;AAChB,MAAM,aAAa,WAAW,KAAK,SAAS,UAAU,CAAC,IACnD,KAAK,SAAS,UAAU,IACxB,KAAK,SAAS,WAAW;AAC7B,MAAM,UAAU,WAAW,KAAK,SAAS,eAAe,CAAC,IACrD,KAAK,SAAS,eAAe,IAC7B,KAAK,SAAS,mBAAmB;AAErC,IAAI,WAAW,UAAU,GAAG;AAC1B,eAAa,YAAY,KAAK,WAAW,QAAQ,OAAO,KAAK,CAAC;AAChE;AAEA,IAAI,WAAW,OAAO,GAAG;AACvB,eAAa,SAAS,KAAK,WAAW,QAAQ,OAAO,YAAY,CAAC;AACpE;AAEA,QAAQ,IAAI,8BAA8B,OAAO,sBAAsB;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @happyvertical/analytics - Unified analytics interface
|
|
3
|
+
*
|
|
4
|
+
* Provides a common interface for interacting with analytics services
|
|
5
|
+
* including Google Analytics 4 and Plausible Analytics.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { getAnalytics } from '@happyvertical/analytics';
|
|
10
|
+
*
|
|
11
|
+
* // Create a GA4 client
|
|
12
|
+
* const analytics = await getAnalytics({
|
|
13
|
+
* type: 'ga4',
|
|
14
|
+
* serviceAccountKey: '/path/to/service-account.json',
|
|
15
|
+
* measurementId: 'G-XXXXXXXXXX',
|
|
16
|
+
* apiSecret: 'your-api-secret'
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Run a report
|
|
20
|
+
* const report = await analytics.runReport('123456789', {
|
|
21
|
+
* dateRanges: [{ startDate: '7daysAgo', endDate: 'today' }],
|
|
22
|
+
* metrics: [{ name: 'activeUsers' }, { name: 'sessions' }],
|
|
23
|
+
* dimensions: [{ name: 'country' }]
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Track an event
|
|
27
|
+
* await analytics.track({
|
|
28
|
+
* name: 'purchase',
|
|
29
|
+
* params: { value: 99.99, currency: 'USD' },
|
|
30
|
+
* clientId: 'user-123'
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export { getAnalytics } from './shared/factory.js';
|
|
35
|
+
export type { AnalyticsAccessRole, AnalyticsAccessVerificationResult, AnalyticsAdminInterface, AnalyticsCapabilities, AnalyticsHealthResult, AnalyticsInterface, AnalyticsSite, AnalyticsUser, AnalyticsUserToken, BaseAnalyticsOptions, BetweenFilter, ConfigOptions, CountingMethod, CreateAnalyticsSiteOptions, CreateAnalyticsUserOptions, CreateDataStreamOptions, CreatePropertyOptions, CustomDimension, CustomDimensionOptions, CustomDimensionScope, CustomMetric, CustomMetricOptions, DataStream, DataStreamType, DateRange, Dimension, DimensionMetadata, DimensionOrderType, Filter, FilterExpression, GA4Options, GetAnalyticsOptions, InListFilter, KeyEvent, KeyEventOptions, ListPropertiesOptions, MatomoOptions, MeasurementUnit, Metric, MetricMetadata, MetricType, MintUserTokenOptions, MinuteRange, NumericFilter, NumericOperation, NumericValue, OrderBy, PageviewEvent, PlausibleOptions, Property, PropertyQuota, QuotaInfo, RealtimeReportOptions, ReportOptions, ReportResult, ReportRow, ServiceAccountCredentials, SetUserAccessOptions, SnippetOptions, StringFilter, StringMatchType, TrackEvent, TrackingSnippet, UpdateAnalyticsSiteOptions, UpdatePropertyOptions, VerifyTokenSiteAccessOptions, VerifyUserSiteAccessOptions, } from './shared/types.js';
|
|
36
|
+
export { AnalyticsError, AuthenticationError, InvalidDimensionError, InvalidMetricError, NotSupportedError, PropertyNotFoundError, QuotaExceededError, RateLimitError, } from './shared/types.js';
|
|
37
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,YAAY,EAEV,mBAAmB,EACnB,iCAAiC,EACjC,uBAAuB,EAEvB,qBAAqB,EACrB,qBAAqB,EAErB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,kBAAkB,EAElB,oBAAoB,EACpB,aAAa,EACb,aAAa,EAEb,cAAc,EACd,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,EACvB,qBAAqB,EACrB,eAAe,EACf,sBAAsB,EAEtB,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,EACnB,UAAU,EAEV,cAAc,EAEd,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,MAAM,EACN,gBAAgB,EAEhB,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,QAAQ,EACR,eAAe,EACf,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,MAAM,EACN,cAAc,EAEd,UAAU,EACV,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,OAAO,EACP,aAAa,EACb,gBAAgB,EAEhB,QAAQ,EACR,aAAa,EACb,SAAS,EACT,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,SAAS,EACT,yBAAyB,EACzB,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,eAAe,EAEf,UAAU,EAEV,eAAe,EACf,0BAA0B,EAC1B,qBAAqB,EACrB,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,GACf,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { loadEnvConfig, ValidationError } from "@happyvertical/utils";
|
|
2
|
+
function isGA4Options(options) {
|
|
3
|
+
return options.type === "ga4";
|
|
4
|
+
}
|
|
5
|
+
function isPlausibleOptions(options) {
|
|
6
|
+
return options.type === "plausible";
|
|
7
|
+
}
|
|
8
|
+
function isMatomoOptions(options) {
|
|
9
|
+
return options.type === "matomo";
|
|
10
|
+
}
|
|
11
|
+
async function getAnalytics(options) {
|
|
12
|
+
const loadedConfig = loadEnvConfig(
|
|
13
|
+
options,
|
|
14
|
+
{
|
|
15
|
+
packageName: "analytics",
|
|
16
|
+
schema: {
|
|
17
|
+
type: "string",
|
|
18
|
+
serviceAccountKey: "string",
|
|
19
|
+
measurementId: "string",
|
|
20
|
+
apiSecret: "string",
|
|
21
|
+
defaultPropertyId: "string",
|
|
22
|
+
apiKey: "string",
|
|
23
|
+
baseUrl: "string",
|
|
24
|
+
defaultSiteId: "string",
|
|
25
|
+
tokenAuth: "string",
|
|
26
|
+
timeout: "number",
|
|
27
|
+
maxRetries: "number",
|
|
28
|
+
cacheTTL: "number"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
options = loadedConfig;
|
|
33
|
+
if (isGA4Options(options)) {
|
|
34
|
+
const { GA4Provider } = await import("./chunks/ga4-6gyDPZRn.js");
|
|
35
|
+
return new GA4Provider(options);
|
|
36
|
+
}
|
|
37
|
+
if (isPlausibleOptions(options)) {
|
|
38
|
+
const { PlausibleProvider } = await import("./chunks/plausible-BxpNa6qF.js");
|
|
39
|
+
return new PlausibleProvider(options);
|
|
40
|
+
}
|
|
41
|
+
if (isMatomoOptions(options)) {
|
|
42
|
+
const { MatomoProvider } = await import("./chunks/matomo-Ds_oRmZ6.js");
|
|
43
|
+
return new MatomoProvider(options);
|
|
44
|
+
}
|
|
45
|
+
throw new ValidationError("Unsupported analytics provider type", {
|
|
46
|
+
supportedTypes: ["ga4", "plausible", "matomo"],
|
|
47
|
+
providedType: options.type
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
class AnalyticsError extends Error {
|
|
51
|
+
constructor(message, code, provider, propertyId) {
|
|
52
|
+
super(message);
|
|
53
|
+
this.code = code;
|
|
54
|
+
this.provider = provider;
|
|
55
|
+
this.propertyId = propertyId;
|
|
56
|
+
this.name = "AnalyticsError";
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
class AuthenticationError extends AnalyticsError {
|
|
60
|
+
constructor(provider, message = "Authentication failed", code = "AUTH_ERROR") {
|
|
61
|
+
super(message, code, provider);
|
|
62
|
+
this.name = "AuthenticationError";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
class RateLimitError extends AnalyticsError {
|
|
66
|
+
retryAfter;
|
|
67
|
+
constructor(provider, retryAfter) {
|
|
68
|
+
super(
|
|
69
|
+
`Rate limit exceeded${retryAfter ? `, retry after ${retryAfter}s` : ""}`,
|
|
70
|
+
"RATE_LIMIT",
|
|
71
|
+
provider
|
|
72
|
+
);
|
|
73
|
+
this.name = "RateLimitError";
|
|
74
|
+
this.retryAfter = retryAfter;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
class PropertyNotFoundError extends AnalyticsError {
|
|
78
|
+
constructor(propertyId, provider) {
|
|
79
|
+
super(
|
|
80
|
+
`Property not found: ${propertyId}`,
|
|
81
|
+
"PROPERTY_NOT_FOUND",
|
|
82
|
+
provider,
|
|
83
|
+
propertyId
|
|
84
|
+
);
|
|
85
|
+
this.name = "PropertyNotFoundError";
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
class InvalidDimensionError extends AnalyticsError {
|
|
89
|
+
dimension;
|
|
90
|
+
constructor(dimension, provider) {
|
|
91
|
+
super(`Invalid dimension: ${dimension}`, "INVALID_DIMENSION", provider);
|
|
92
|
+
this.name = "InvalidDimensionError";
|
|
93
|
+
this.dimension = dimension;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
class InvalidMetricError extends AnalyticsError {
|
|
97
|
+
metric;
|
|
98
|
+
constructor(metric, provider) {
|
|
99
|
+
super(`Invalid metric: ${metric}`, "INVALID_METRIC", provider);
|
|
100
|
+
this.name = "InvalidMetricError";
|
|
101
|
+
this.metric = metric;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
class QuotaExceededError extends AnalyticsError {
|
|
105
|
+
quotaType;
|
|
106
|
+
constructor(provider, quotaType) {
|
|
107
|
+
super(
|
|
108
|
+
`Quota exceeded${quotaType ? `: ${quotaType}` : ""}`,
|
|
109
|
+
"QUOTA_EXCEEDED",
|
|
110
|
+
provider
|
|
111
|
+
);
|
|
112
|
+
this.name = "QuotaExceededError";
|
|
113
|
+
this.quotaType = quotaType;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
class NotSupportedError extends AnalyticsError {
|
|
117
|
+
feature;
|
|
118
|
+
constructor(feature, provider) {
|
|
119
|
+
super(`Feature not supported: ${feature}`, "NOT_SUPPORTED", provider);
|
|
120
|
+
this.name = "NotSupportedError";
|
|
121
|
+
this.feature = feature;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export {
|
|
125
|
+
AnalyticsError,
|
|
126
|
+
AuthenticationError,
|
|
127
|
+
InvalidDimensionError,
|
|
128
|
+
InvalidMetricError,
|
|
129
|
+
NotSupportedError,
|
|
130
|
+
PropertyNotFoundError,
|
|
131
|
+
QuotaExceededError,
|
|
132
|
+
RateLimitError,
|
|
133
|
+
getAnalytics
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/shared/factory.ts","../src/shared/types.ts"],"sourcesContent":["/**\n * Factory function for creating analytics provider instances\n */\n\nimport { loadEnvConfig, ValidationError } from '@happyvertical/utils';\n\nimport type {\n AnalyticsInterface,\n GA4Options,\n GetAnalyticsOptions,\n MatomoOptions,\n PlausibleOptions,\n} from './types.js';\n\n/**\n * Type guard for GA4 options\n */\nfunction isGA4Options(options: GetAnalyticsOptions): options is GA4Options {\n return options.type === 'ga4';\n}\n\n/**\n * Type guard for Plausible options\n */\nfunction isPlausibleOptions(\n options: GetAnalyticsOptions,\n): options is PlausibleOptions {\n return options.type === 'plausible';\n}\n\n/**\n * Type guard for Matomo options\n */\nfunction isMatomoOptions(\n options: GetAnalyticsOptions,\n): options is MatomoOptions {\n return options.type === 'matomo';\n}\n\n/**\n * Creates an analytics provider instance based on the provided options.\n *\n * Supports environment variable configuration using the pattern:\n * - HAVE_ANALYTICS_TYPE → provider type ('ga4' | 'plausible' | 'matomo')\n * - HAVE_ANALYTICS_SERVICE_ACCOUNT_KEY → path to service account JSON or JSON string\n * - HAVE_ANALYTICS_MEASUREMENT_ID → GA4 measurement ID (G-XXXXXXX)\n * - HAVE_ANALYTICS_API_SECRET → GA4 API secret for Measurement Protocol\n * - HAVE_ANALYTICS_DEFAULT_PROPERTY_ID → default property ID\n * - HAVE_ANALYTICS_API_KEY → Plausible API key\n * - HAVE_ANALYTICS_BASE_URL → Plausible / Matomo base URL (for self-hosted)\n * - HAVE_ANALYTICS_DEFAULT_SITE_ID → Plausible / Matomo default site ID\n * - HAVE_ANALYTICS_TOKEN_AUTH → Matomo per-user token_auth\n * - HAVE_ANALYTICS_TIMEOUT → request timeout in milliseconds\n * - HAVE_ANALYTICS_MAX_RETRIES → maximum retry attempts\n * - HAVE_ANALYTICS_CACHE_TTL → cache TTL in milliseconds\n *\n * User-provided options always take precedence over environment variables.\n *\n * @param options - Configuration options for the analytics provider\n * @returns Promise resolving to an analytics provider instance\n * @throws {ValidationError} When the provider type is unsupported or required options are missing\n *\n * @example\n * ```typescript\n * // Create GA4 client with explicit options\n * const ga4 = await getAnalytics({\n * type: 'ga4',\n * serviceAccountKey: '/path/to/service-account.json',\n * measurementId: 'G-XXXXXXXXXX',\n * apiSecret: 'your-api-secret'\n * });\n *\n * // Create Plausible client\n * const plausible = await getAnalytics({\n * type: 'plausible',\n * apiKey: 'your-api-key',\n * baseUrl: 'https://plausible.io' // or self-hosted URL\n * });\n *\n * // Use environment variables\n * // Set: HAVE_ANALYTICS_TYPE=ga4, HAVE_ANALYTICS_SERVICE_ACCOUNT_KEY=/path/to/key.json, etc.\n * const client = await getAnalytics({ type: 'ga4' });\n * ```\n */\nexport async function getAnalytics(\n options: GetAnalyticsOptions,\n): Promise<AnalyticsInterface> {\n // Load environment variables with user options taking precedence\n const loadedConfig = loadEnvConfig(\n options as unknown as Record<string, unknown>,\n {\n packageName: 'analytics',\n schema: {\n type: 'string',\n serviceAccountKey: 'string',\n measurementId: 'string',\n apiSecret: 'string',\n defaultPropertyId: 'string',\n apiKey: 'string',\n baseUrl: 'string',\n defaultSiteId: 'string',\n tokenAuth: 'string',\n timeout: 'number',\n maxRetries: 'number',\n cacheTTL: 'number',\n },\n },\n );\n options = loadedConfig as unknown as GetAnalyticsOptions;\n\n if (isGA4Options(options)) {\n const { GA4Provider } = await import('./providers/ga4.js');\n return new GA4Provider(options);\n }\n\n if (isPlausibleOptions(options)) {\n const { PlausibleProvider } = await import('./providers/plausible.js');\n return new PlausibleProvider(options);\n }\n\n if (isMatomoOptions(options)) {\n const { MatomoProvider } = await import('./providers/matomo.js');\n return new MatomoProvider(options);\n }\n\n throw new ValidationError('Unsupported analytics provider type', {\n supportedTypes: ['ga4', 'plausible', 'matomo'],\n providedType: (options as { type?: string }).type,\n });\n}\n","/**\n * Core types and interfaces for the Analytics library\n */\n\n// =============================================================================\n// Base Options\n// =============================================================================\n\n/**\n * Base configuration options for all analytics providers\n */\nexport interface BaseAnalyticsOptions {\n /** Request timeout in milliseconds */\n timeout?: number;\n /** Maximum retry attempts for failed requests */\n maxRetries?: number;\n /** Cache TTL in milliseconds for metadata operations */\n cacheTTL?: number;\n}\n\n/**\n * Service account credentials for Google APIs\n */\nexport interface ServiceAccountCredentials {\n type: 'service_account';\n project_id: string;\n private_key_id: string;\n private_key: string;\n client_email: string;\n client_id: string;\n auth_uri: string;\n token_uri: string;\n auth_provider_x509_cert_url: string;\n client_x509_cert_url: string;\n}\n\n// =============================================================================\n// Provider Options (Discriminated Union)\n// =============================================================================\n\n/**\n * Google Analytics 4 provider options\n */\nexport interface GA4Options extends BaseAnalyticsOptions {\n type: 'ga4';\n /**\n * Service account credentials for Admin API and Data API\n * Can be path to JSON key file or parsed JSON object\n */\n serviceAccountKey?: string | ServiceAccountCredentials;\n /**\n * Measurement ID (G-XXXXXXX) for Measurement Protocol\n * Required for server-side event tracking\n */\n measurementId?: string;\n /**\n * API Secret for Measurement Protocol\n * Required for server-side event tracking\n */\n apiSecret?: string;\n /**\n * Default property ID for operations that don't specify one\n */\n defaultPropertyId?: string;\n}\n\n/**\n * Plausible Analytics provider options\n */\nexport interface PlausibleOptions extends BaseAnalyticsOptions {\n type: 'plausible';\n /**\n * Plausible API key\n */\n apiKey: string;\n /**\n * Base URL for self-hosted instances\n * @default \"https://plausible.io\"\n */\n baseUrl?: string;\n /**\n * Default site ID (domain) for operations\n */\n defaultSiteId?: string;\n}\n\n/**\n * Matomo Analytics provider options\n *\n * Matomo's Reporting API authenticates via per-user `token_auth` values; admin\n * provisioning operations require a token belonging to a super-user.\n */\nexport interface MatomoOptions extends BaseAnalyticsOptions {\n type: 'matomo';\n /**\n * Matomo base URL (e.g. `https://matomo.example.com`).\n *\n * Trailing slashes and explicit `/index.php` suffixes are normalized.\n */\n baseUrl: string;\n /**\n * `token_auth` for the calling user. Required for all reporting calls.\n *\n * For admin provisioning (createSite/createUser/etc.) this token must\n * belong to a Matomo super-user.\n */\n tokenAuth: string;\n /**\n * Default site ID (`idSite`) for operations that don't specify one.\n */\n defaultSiteId?: string;\n}\n\n/**\n * Union type for all provider options\n */\nexport type GetAnalyticsOptions = GA4Options | PlausibleOptions | MatomoOptions;\n\n// =============================================================================\n// Property Types\n// =============================================================================\n\n/**\n * Analytics property/site representation\n */\nexport interface Property {\n /** Unique identifier */\n id: string;\n /** Internal name (GA4: properties/123456789) */\n name: string;\n /** Human-readable display name */\n displayName: string;\n /** Creation timestamp (ISO 8601) */\n createTime: string;\n /** Last update timestamp (ISO 8601) */\n updateTime?: string;\n /** Property timezone */\n timeZone?: string;\n /** Currency code (e.g., 'USD', 'EUR') */\n currencyCode?: string;\n /** Industry category */\n industryCategory?: string;\n /** Service level */\n serviceLevel?: 'STANDARD' | 'PREMIUM';\n}\n\n/**\n * Options for listing properties\n */\nexport interface ListPropertiesOptions {\n /**\n * Controls whether the provider should hydrate discovered properties with\n * full metadata.\n *\n * Providers that support hydration should default this to `true` to\n * preserve the existing `listProperties()` behavior. Set this to `false`\n * to use discovery-only metadata, which may omit fields like `createTime`,\n * `updateTime`, `timeZone`, and `currencyCode`.\n */\n hydrate?: boolean;\n}\n\n/**\n * Options for creating a new property\n */\nexport interface CreatePropertyOptions {\n /** Human-readable display name */\n displayName: string;\n /** Timezone (e.g., 'America/Los_Angeles') */\n timeZone?: string;\n /** Currency code (e.g., 'USD') */\n currencyCode?: string;\n /** Industry category */\n industryCategory?: string;\n /** Parent account (GA4: accounts/{account_id}) */\n parent?: string;\n}\n\n/**\n * Options for updating a property\n */\nexport interface UpdatePropertyOptions {\n /** Human-readable display name */\n displayName?: string;\n /** Timezone */\n timeZone?: string;\n /** Currency code */\n currencyCode?: string;\n /** Industry category */\n industryCategory?: string;\n}\n\n// =============================================================================\n// Data Stream Types\n// =============================================================================\n\n/**\n * Data stream types\n */\nexport type DataStreamType =\n | 'WEB_DATA_STREAM'\n | 'ANDROID_APP_DATA_STREAM'\n | 'IOS_APP_DATA_STREAM';\n\n/**\n * Data stream representation\n */\nexport interface DataStream {\n /** Unique identifier */\n id: string;\n /** Stream type */\n type: DataStreamType;\n /** Human-readable display name */\n displayName: string;\n /** Measurement ID for web streams (G-XXXXXXX) */\n measurementId?: string;\n /** Firebase App ID for app streams */\n firebaseAppId?: string;\n /** Default URI for web streams */\n defaultUri?: string;\n /** Creation timestamp */\n createTime: string;\n /** Last update timestamp */\n updateTime?: string;\n}\n\n/**\n * Options for creating a data stream\n */\nexport interface CreateDataStreamOptions {\n /** Stream type */\n type: DataStreamType;\n /** Human-readable display name */\n displayName: string;\n /** Default URI for web streams */\n defaultUri?: string;\n /** Bundle ID for iOS apps */\n bundleId?: string;\n /** Package name for Android apps */\n packageName?: string;\n}\n\n// =============================================================================\n// Custom Dimension/Metric Types\n// =============================================================================\n\n/**\n * Scope for custom dimensions\n */\nexport type CustomDimensionScope = 'EVENT' | 'USER' | 'ITEM';\n\n/**\n * Custom dimension representation\n */\nexport interface CustomDimension {\n /** Unique identifier */\n id: string;\n /** Resource name */\n name: string;\n /** Parameter name used in events */\n parameterName: string;\n /** Human-readable display name */\n displayName: string;\n /** Description */\n description?: string;\n /** Scope of the dimension */\n scope: CustomDimensionScope;\n /** Whether to disallow ads personalization */\n disallowAdsPersonalization?: boolean;\n}\n\n/**\n * Options for creating a custom dimension\n */\nexport interface CustomDimensionOptions {\n /** Parameter name used in events */\n parameterName: string;\n /** Human-readable display name */\n displayName: string;\n /** Description */\n description?: string;\n /** Scope of the dimension */\n scope: CustomDimensionScope;\n /** Whether to disallow ads personalization */\n disallowAdsPersonalization?: boolean;\n}\n\n/**\n * Measurement unit for custom metrics\n */\nexport type MeasurementUnit =\n | 'STANDARD'\n | 'CURRENCY'\n | 'FEET'\n | 'METERS'\n | 'KILOMETERS'\n | 'MILES'\n | 'MILLISECONDS'\n | 'SECONDS'\n | 'MINUTES'\n | 'HOURS';\n\n/**\n * Custom metric representation\n */\nexport interface CustomMetric {\n /** Unique identifier */\n id: string;\n /** Resource name */\n name: string;\n /** Parameter name used in events */\n parameterName: string;\n /** Human-readable display name */\n displayName: string;\n /** Description */\n description?: string;\n /** Scope (always EVENT for metrics) */\n scope: 'EVENT';\n /** Measurement unit */\n measurementUnit: MeasurementUnit;\n /** Restricted metric type */\n restrictedMetricType?: 'COST_DATA' | 'REVENUE_DATA';\n}\n\n/**\n * Options for creating a custom metric\n */\nexport interface CustomMetricOptions {\n /** Parameter name used in events */\n parameterName: string;\n /** Human-readable display name */\n displayName: string;\n /** Description */\n description?: string;\n /** Measurement unit */\n measurementUnit: MeasurementUnit;\n /** Restricted metric type */\n restrictedMetricType?: 'COST_DATA' | 'REVENUE_DATA';\n}\n\n// =============================================================================\n// Key Event (Conversion) Types\n// =============================================================================\n\n/**\n * Counting method for key events\n */\nexport type CountingMethod = 'ONCE_PER_EVENT' | 'ONCE_PER_SESSION';\n\n/**\n * Key event (conversion) representation\n */\nexport interface KeyEvent {\n /** Unique identifier */\n id: string;\n /** Resource name */\n name: string;\n /** Event name that triggers this key event */\n eventName: string;\n /** Creation timestamp */\n createTime: string;\n /** How to count the conversion */\n countingMethod?: CountingMethod;\n /** Default value for the conversion */\n defaultValue?: {\n numericValue?: number;\n currencyCode?: string;\n };\n}\n\n/**\n * Options for creating a key event\n */\nexport interface KeyEventOptions {\n /** Event name that triggers this key event */\n eventName: string;\n /** How to count the conversion */\n countingMethod?: CountingMethod;\n /** Default value for the conversion */\n defaultValue?: {\n numericValue?: number;\n currencyCode?: string;\n };\n}\n\n// =============================================================================\n// Reporting Types\n// =============================================================================\n\n/**\n * Date range for reports\n */\nexport interface DateRange {\n /** Start date (YYYY-MM-DD or relative: 'today', 'yesterday', '7daysAgo', '30daysAgo') */\n startDate: string;\n /** End date (YYYY-MM-DD or relative: 'today', 'yesterday') */\n endDate: string;\n /** Optional name for this date range */\n name?: string;\n}\n\n/**\n * Dimension specification for reports\n */\nexport interface Dimension {\n /** Dimension name (e.g., 'country', 'deviceCategory') */\n name: string;\n}\n\n/**\n * Metric specification for reports\n */\nexport interface Metric {\n /** Metric name (e.g., 'activeUsers', 'sessions') */\n name: string;\n}\n\n/**\n * Filter match types\n */\nexport type StringMatchType =\n | 'EXACT'\n | 'BEGINS_WITH'\n | 'ENDS_WITH'\n | 'CONTAINS'\n | 'FULL_REGEXP'\n | 'PARTIAL_REGEXP';\n\n/**\n * Numeric filter operations\n */\nexport type NumericOperation =\n | 'EQUAL'\n | 'LESS_THAN'\n | 'LESS_THAN_OR_EQUAL'\n | 'GREATER_THAN'\n | 'GREATER_THAN_OR_EQUAL';\n\n/**\n * Filter value (numeric)\n */\nexport interface NumericValue {\n int64Value?: string;\n doubleValue?: number;\n}\n\n/**\n * String filter specification\n */\nexport interface StringFilter {\n matchType: StringMatchType;\n value: string;\n caseSensitive?: boolean;\n}\n\n/**\n * In-list filter specification\n */\nexport interface InListFilter {\n values: string[];\n caseSensitive?: boolean;\n}\n\n/**\n * Numeric filter specification\n */\nexport interface NumericFilter {\n operation: NumericOperation;\n value: NumericValue;\n}\n\n/**\n * Between filter specification\n */\nexport interface BetweenFilter {\n fromValue: NumericValue;\n toValue: NumericValue;\n}\n\n/**\n * Individual filter specification\n */\nexport interface Filter {\n fieldName: string;\n stringFilter?: StringFilter;\n inListFilter?: InListFilter;\n numericFilter?: NumericFilter;\n betweenFilter?: BetweenFilter;\n}\n\n/**\n * Filter expression (supports AND/OR/NOT combinations)\n */\nexport interface FilterExpression {\n andGroup?: { expressions: FilterExpression[] };\n orGroup?: { expressions: FilterExpression[] };\n notExpression?: FilterExpression;\n filter?: Filter;\n}\n\n/**\n * Order type for dimension sorting\n */\nexport type DimensionOrderType =\n | 'ALPHANUMERIC'\n | 'CASE_INSENSITIVE_ALPHANUMERIC'\n | 'NUMERIC';\n\n/**\n * Order specification\n */\nexport interface OrderBy {\n metric?: { metricName: string };\n dimension?: {\n dimensionName: string;\n orderType?: DimensionOrderType;\n };\n desc?: boolean;\n}\n\n/**\n * Minute range for realtime reports\n */\nexport interface MinuteRange {\n name?: string;\n startMinutesAgo: number;\n endMinutesAgo: number;\n}\n\n/**\n * Report request options\n */\nexport interface ReportOptions {\n /** Date ranges to query */\n dateRanges: DateRange[];\n /** Dimensions to group by */\n dimensions?: Dimension[];\n /** Metrics to retrieve */\n metrics: Metric[];\n /** Dimension filter expression */\n dimensionFilter?: FilterExpression;\n /** Metric filter expression */\n metricFilter?: FilterExpression;\n /** Result offset for pagination */\n offset?: number;\n /** Maximum results to return */\n limit?: number;\n /** Sort order */\n orderBys?: OrderBy[];\n /** Whether to keep empty rows */\n keepEmptyRows?: boolean;\n /** Whether to return property quota information */\n returnPropertyQuota?: boolean;\n}\n\n/**\n * Realtime report options\n */\nexport interface RealtimeReportOptions {\n /** Dimensions to group by */\n dimensions?: Dimension[];\n /** Metrics to retrieve */\n metrics?: Metric[];\n /** Dimension filter expression */\n dimensionFilter?: FilterExpression;\n /** Metric filter expression */\n metricFilter?: FilterExpression;\n /** Maximum results to return */\n limit?: number;\n /** Minute ranges to query */\n minuteRanges?: MinuteRange[];\n}\n\n/**\n * Report row\n */\nexport interface ReportRow {\n dimensionValues: { value: string }[];\n metricValues: { value: string }[];\n}\n\n/**\n * Quota information\n */\nexport interface QuotaInfo {\n consumed: number;\n remaining: number;\n}\n\n/**\n * Property quota information\n */\nexport interface PropertyQuota {\n tokensPerDay: QuotaInfo;\n tokensPerHour: QuotaInfo;\n concurrentRequests: QuotaInfo;\n}\n\n/**\n * Report result\n */\nexport interface ReportResult {\n /** Column headers for dimensions */\n dimensionHeaders: { name: string }[];\n /** Column headers for metrics */\n metricHeaders: { name: string; type: string }[];\n /** Data rows */\n rows: ReportRow[];\n /** Total row count */\n rowCount?: number;\n /** Report metadata */\n metadata?: {\n currencyCode?: string;\n timeZone?: string;\n dataLossFromOtherRow?: boolean;\n emptyReason?: string;\n };\n /** Property quota usage */\n propertyQuota?: PropertyQuota;\n}\n\n// =============================================================================\n// Metadata Types\n// =============================================================================\n\n/**\n * Metric type\n */\nexport type MetricType =\n | 'METRIC_TYPE_UNSPECIFIED'\n | 'TYPE_INTEGER'\n | 'TYPE_FLOAT'\n | 'TYPE_SECONDS'\n | 'TYPE_MILLISECONDS'\n | 'TYPE_MINUTES'\n | 'TYPE_HOURS'\n | 'TYPE_STANDARD'\n | 'TYPE_CURRENCY'\n | 'TYPE_FEET'\n | 'TYPE_MILES'\n | 'TYPE_METERS'\n | 'TYPE_KILOMETERS';\n\n/**\n * Metric metadata\n */\nexport interface MetricMetadata {\n /** API name for the metric */\n apiName: string;\n /** UI display name */\n uiName: string;\n /** Description */\n description: string;\n /** Deprecated API names */\n deprecatedApiNames?: string[];\n /** Metric data type */\n type: MetricType;\n /** Expression for calculated metrics */\n expression?: string;\n /** Whether this is a custom definition */\n customDefinition?: boolean;\n /** Reasons metric may be blocked */\n blockedReasons?: string[];\n /** Category */\n category?: string;\n}\n\n/**\n * Dimension metadata\n */\nexport interface DimensionMetadata {\n /** API name for the dimension */\n apiName: string;\n /** UI display name */\n uiName: string;\n /** Description */\n description: string;\n /** Deprecated API names */\n deprecatedApiNames?: string[];\n /** Whether this is a custom definition */\n customDefinition?: boolean;\n /** Category */\n category?: string;\n}\n\n// =============================================================================\n// Event Tracking Types\n// =============================================================================\n\n/**\n * Track event payload\n */\nexport interface TrackEvent {\n /** Event name */\n name: string;\n /** Event parameters */\n params?: Record<string, string | number | boolean>;\n /** Client ID for anonymous tracking */\n clientId?: string;\n /** User ID for identified tracking */\n userId?: string;\n /** Event timestamp (Unix epoch in microseconds) */\n timestamp?: number;\n /** Whether to disable personalized ads */\n nonPersonalizedAds?: boolean;\n}\n\n/**\n * Pageview event payload\n */\nexport interface PageviewEvent {\n /** Page path */\n pagePath: string;\n /** Page title */\n pageTitle?: string;\n /** Full page location URL */\n pageLocation?: string;\n /** Client ID for anonymous tracking */\n clientId?: string;\n /** User ID for identified tracking */\n userId?: string;\n /** Additional parameters */\n params?: Record<string, string | number | boolean>;\n}\n\n// =============================================================================\n// Client-Side Snippet Types\n// =============================================================================\n\n/**\n * Generated tracking snippet\n */\nexport interface TrackingSnippet {\n /** HTML snippet ready to embed */\n html: string;\n /** Configuration object */\n config: Record<string, unknown>;\n /** External script URLs */\n scripts: string[];\n}\n\n/**\n * Options for snippet generation\n */\nexport interface SnippetOptions {\n /** Whether to anonymize IP addresses */\n anonymizeIp?: boolean;\n /** Whether to send initial pageview */\n sendPageView?: boolean;\n /** Cookie flags */\n cookieFlags?: string;\n /** Custom configuration options */\n customConfig?: Record<string, unknown>;\n}\n\n/**\n * Options for config generation\n */\nexport interface ConfigOptions {\n /** Whether to anonymize IP addresses */\n anonymizeIp?: boolean;\n /** Whether to send initial pageview */\n sendPageView?: boolean;\n /** User ID for cross-device tracking */\n userId?: string;\n /** Custom dimensions to set */\n customDimensions?: Record<string, string>;\n}\n\n// =============================================================================\n// Capabilities\n// =============================================================================\n\n/**\n * Analytics provider capabilities\n */\nexport interface AnalyticsCapabilities {\n /** Whether property management is supported */\n propertyManagement: boolean;\n /** Whether data streams are supported */\n dataStreams: boolean;\n /** Whether custom dimensions are supported */\n customDimensions: boolean;\n /** Whether custom metrics are supported */\n customMetrics: boolean;\n /** Whether key events (conversions) are supported */\n keyEvents: boolean;\n /** Whether reporting is supported */\n reporting: boolean;\n /** Whether realtime reporting is supported */\n realtimeReporting: boolean;\n /** Whether server-side tracking is supported */\n serverSideTracking: boolean;\n /** Whether client-side snippet generation is supported */\n clientSideSnippet: boolean;\n /** Whether user identification is supported */\n userIdentification: boolean;\n /** Whether batch tracking is supported */\n batchTracking: boolean;\n}\n\n// =============================================================================\n// Analytics Interface\n// =============================================================================\n\n/**\n * Core analytics interface that all providers must implement\n */\nexport interface AnalyticsInterface {\n // -------------------------------------------------------------------------\n // Property Management\n // -------------------------------------------------------------------------\n\n /**\n * Create a new analytics property\n */\n createProperty(options: CreatePropertyOptions): Promise<Property>;\n\n /**\n * List all properties accessible to this account\n */\n listProperties(options?: ListPropertiesOptions): Promise<Property[]>;\n\n /**\n * Get a specific property by ID\n */\n getProperty(propertyId: string): Promise<Property>;\n\n /**\n * Update a property\n */\n updateProperty(\n propertyId: string,\n data: UpdatePropertyOptions,\n ): Promise<Property>;\n\n /**\n * Delete a property\n */\n deleteProperty(propertyId: string): Promise<void>;\n\n // -------------------------------------------------------------------------\n // Data Streams\n // -------------------------------------------------------------------------\n\n /**\n * Get all data streams for a property\n */\n getDataStreams(propertyId: string): Promise<DataStream[]>;\n\n /**\n * Create a new data stream\n */\n createDataStream(\n propertyId: string,\n options: CreateDataStreamOptions,\n ): Promise<DataStream>;\n\n /**\n * Delete a data stream\n */\n deleteDataStream(propertyId: string, streamId: string): Promise<void>;\n\n // -------------------------------------------------------------------------\n // Custom Definitions\n // -------------------------------------------------------------------------\n\n /**\n * Get all custom dimensions for a property\n */\n getCustomDimensions(propertyId: string): Promise<CustomDimension[]>;\n\n /**\n * Create a new custom dimension\n */\n createCustomDimension(\n propertyId: string,\n options: CustomDimensionOptions,\n ): Promise<CustomDimension>;\n\n /**\n * Archive (soft-delete) a custom dimension\n */\n archiveCustomDimension(\n propertyId: string,\n dimensionId: string,\n ): Promise<void>;\n\n /**\n * Get all custom metrics for a property\n */\n getCustomMetrics(propertyId: string): Promise<CustomMetric[]>;\n\n /**\n * Create a new custom metric\n */\n createCustomMetric(\n propertyId: string,\n options: CustomMetricOptions,\n ): Promise<CustomMetric>;\n\n /**\n * Archive (soft-delete) a custom metric\n */\n archiveCustomMetric(propertyId: string, metricId: string): Promise<void>;\n\n // -------------------------------------------------------------------------\n // Key Events (Conversions)\n // -------------------------------------------------------------------------\n\n /**\n * Get all key events for a property\n */\n getKeyEvents(propertyId: string): Promise<KeyEvent[]>;\n\n /**\n * Create a new key event\n */\n createKeyEvent(\n propertyId: string,\n options: KeyEventOptions,\n ): Promise<KeyEvent>;\n\n /**\n * Delete a key event\n */\n deleteKeyEvent(propertyId: string, eventId: string): Promise<void>;\n\n // -------------------------------------------------------------------------\n // Reporting\n // -------------------------------------------------------------------------\n\n /**\n * Run a report query\n */\n runReport(propertyId: string, options: ReportOptions): Promise<ReportResult>;\n\n /**\n * Run a realtime report query\n */\n runRealtimeReport(\n propertyId: string,\n options?: RealtimeReportOptions,\n ): Promise<ReportResult>;\n\n /**\n * Get available metrics for a property\n */\n getMetrics(propertyId: string): Promise<MetricMetadata[]>;\n\n /**\n * Get available dimensions for a property\n */\n getDimensions(propertyId: string): Promise<DimensionMetadata[]>;\n\n // -------------------------------------------------------------------------\n // Event Tracking (Server-Side)\n // -------------------------------------------------------------------------\n\n /**\n * Track a single event\n */\n track(event: TrackEvent): Promise<void>;\n\n /**\n * Track a pageview\n */\n trackPageview(pageview: PageviewEvent): Promise<void>;\n\n /**\n * Track multiple events in a batch\n */\n trackBatch(events: TrackEvent[]): Promise<void>;\n\n /**\n * Identify a user with traits\n */\n identify(userId: string, traits?: Record<string, unknown>): Promise<void>;\n\n // -------------------------------------------------------------------------\n // Client-Side Helpers\n // -------------------------------------------------------------------------\n\n /**\n * Generate a tracking snippet for embedding in HTML\n */\n generateTrackingSnippet(\n propertyId: string,\n options?: SnippetOptions,\n ): TrackingSnippet;\n\n /**\n * Generate a configuration object for programmatic use\n */\n generateConfig(\n propertyId: string,\n options?: ConfigOptions,\n ): Record<string, unknown>;\n\n // -------------------------------------------------------------------------\n // Provider Info\n // -------------------------------------------------------------------------\n\n /**\n * Get provider capabilities\n */\n getCapabilities(): Promise<AnalyticsCapabilities>;\n\n /**\n * Provisioning admin operations exposed by providers that support them.\n *\n * Optional. Providers that don't support tenant/site/user provisioning leave\n * this undefined. Implementations should mirror the pattern used by\n * `@happyvertical/ai`'s `AIAdminInterface`.\n */\n admin?: AnalyticsAdminInterface;\n}\n\n// =============================================================================\n// Admin Provisioning\n// =============================================================================\n\n/**\n * Site descriptor returned by admin providers.\n */\nexport interface AnalyticsSite {\n /**\n * Provider site ID. For Matomo this is the numeric `idSite` as a string.\n */\n id: string;\n /**\n * Human-readable site name as stored by the provider.\n */\n name: string;\n /**\n * Primary URL or domain for the site.\n */\n url?: string;\n /**\n * Site timezone (e.g. `America/Edmonton`).\n */\n timezone?: string;\n /**\n * Currency code where applicable (e.g. `CAD`).\n */\n currency?: string;\n /**\n * Tenant identifier this site is associated with, when supplied at create time.\n */\n tenantId?: string;\n /**\n * Provider that owns this site descriptor.\n */\n provider: string;\n /**\n * Raw provider response.\n */\n raw?: unknown;\n}\n\n/**\n * Options for creating a site.\n */\nexport interface CreateAnalyticsSiteOptions {\n /**\n * Human-readable site name.\n */\n name: string;\n /**\n * Site URL(s). At least one is required for Matomo.\n */\n urls: string[];\n /**\n * Site timezone (IANA, e.g. `America/Edmonton`). Defaults to provider default.\n */\n timezone?: string;\n /**\n * Currency code. Defaults to provider default.\n */\n currency?: string;\n /**\n * Optional tenant identifier to associate with this site.\n */\n tenantId?: string;\n /**\n * Provider-specific request body overrides.\n */\n raw?: Record<string, unknown>;\n}\n\n/**\n * Options for updating an existing site.\n *\n * Reuses the `createSite` field shapes — every field except `siteId` is\n * optional, and omitted fields are left unchanged on the provider (partial\n * update).\n */\nexport interface UpdateAnalyticsSiteOptions\n extends Partial<CreateAnalyticsSiteOptions> {\n /**\n * Provider site ID of the site to update. For Matomo this is the numeric\n * `idSite` as a string.\n */\n siteId: string;\n}\n\n/**\n * User access role assignable to an analytics site.\n */\nexport type AnalyticsAccessRole = 'noaccess' | 'view' | 'write' | 'admin';\n\n/**\n * Analytics user descriptor returned by admin providers.\n */\nexport interface AnalyticsUser {\n /**\n * Login or username used to authenticate the user.\n */\n login: string;\n /**\n * Email address recorded for the user.\n */\n email?: string;\n /**\n * Tenant identifier this user is associated with, when supplied at create time.\n */\n tenantId?: string;\n /**\n * Whether the user has been granted super-user access.\n */\n isSuperUser?: boolean;\n /**\n * Provider that owns this user descriptor.\n */\n provider: string;\n /**\n * Raw provider response.\n */\n raw?: unknown;\n}\n\n/**\n * Options for creating a user.\n */\nexport interface CreateAnalyticsUserOptions {\n /**\n * Login or username for the new user.\n */\n login: string;\n /**\n * Email address for the new user.\n */\n email: string;\n /**\n * Initial password. Implementations may generate one if omitted, but should\n * surface it on the returned user. For Matomo the password is required.\n */\n password?: string;\n /**\n * Optional tenant identifier to associate with this user (stored in\n * provider metadata where supported).\n */\n tenantId?: string;\n /**\n * Provider-specific request body overrides.\n */\n raw?: Record<string, unknown>;\n}\n\n/**\n * Options for granting site access to a user.\n */\nexport interface SetUserAccessOptions {\n /**\n * Login or username to grant access to.\n */\n login: string;\n /**\n * Access level to grant.\n */\n access: AnalyticsAccessRole;\n /**\n * Site IDs the access applies to.\n */\n siteIds: string[];\n}\n\n/**\n * Options for verifying that a user has sufficient access to a site.\n */\nexport interface VerifyUserSiteAccessOptions {\n /**\n * Login or username to inspect.\n */\n login: string;\n /**\n * Site ID the user should be able to access.\n */\n siteId: string;\n /**\n * Minimum required access. Defaults to `view`.\n */\n minimumAccess?: AnalyticsAccessRole;\n}\n\n/**\n * Options for verifying that a token can read a site.\n */\nexport interface VerifyTokenSiteAccessOptions {\n /**\n * Token to probe. This is the token under test, not necessarily the admin\n * token used by the provider instance.\n */\n tokenAuth: string;\n /**\n * Site ID the token should be able to read.\n */\n siteId: string;\n}\n\n/**\n * Result returned by access-verification helpers.\n */\nexport interface AnalyticsAccessVerificationResult {\n /**\n * Whether the requested access check passed.\n */\n ok: boolean;\n /**\n * Provider that performed the check.\n */\n provider: string;\n /**\n * Login that was inspected, when the check targets a user.\n */\n login?: string;\n /**\n * Site ID that was inspected.\n */\n siteId: string;\n /**\n * Observed access level. Token probes report `view` when the token can read\n * the site and `noaccess` when it cannot.\n */\n access?: AnalyticsAccessRole;\n /**\n * Required access level used by the check.\n */\n requiredAccess?: AnalyticsAccessRole;\n /**\n * Failure reason when `ok` is false.\n */\n error?: string;\n /**\n * Provider-specific failure code when `ok` is false.\n */\n errorCode?: string;\n /**\n * Raw provider response. This is intended for debugging and may include more\n * provider data than the specific access check asked for; avoid logging it\n * verbatim in application logs.\n */\n raw?: unknown;\n}\n\n/**\n * Options for minting a per-user auth token scoped to a user's permissions.\n */\nexport interface MintUserTokenOptions {\n /**\n * Login or username to mint the token for.\n */\n login: string;\n /**\n * Description of the token (where supported).\n */\n description?: string;\n /**\n * The target user's password. Matomo's `createAppSpecificTokenAuth`\n * confirms the *target* user's password (not the caller's) — this prevents\n * a stolen super-user token from minting tokens for arbitrary other users.\n *\n * Other providers may not need this; it's optional in the shared interface\n * but Matomo will throw without it.\n */\n passwordConfirmation?: string;\n}\n\n/**\n * Auth token descriptor returned by admin providers.\n */\nexport interface AnalyticsUserToken {\n /**\n * The token value. Show-once for most providers; not stored in plaintext on\n * the provider side.\n */\n token: string;\n /**\n * Login the token belongs to.\n */\n login: string;\n /**\n * Description recorded on the provider.\n */\n description?: string;\n /**\n * Provider that owns this token descriptor.\n */\n provider: string;\n /**\n * Raw provider response.\n */\n raw?: unknown;\n}\n\n/**\n * Result of a provider health probe.\n */\nexport interface AnalyticsHealthResult {\n /**\n * Whether the probe was able to reach the provider AND complete an authed\n * round-trip (if the probe is authed).\n */\n ok: boolean;\n /**\n * Provider version string, when available.\n */\n version?: string;\n /**\n * Failure reason when `ok` is false.\n */\n error?: string;\n}\n\n/**\n * Admin operations exposed by analytics providers that support provisioning.\n *\n * Mirrors the shape of `@happyvertical/ai`'s `AIAdminInterface`. Methods that a\n * particular provider can't support (e.g. `mintUserToken` against GA4) are left\n * out of that provider's admin object — callers should feature-check via\n * `typeof admin.mintUserToken === 'function'`.\n *\n * Because that feature-check idiom typically narrows a method into a local\n * (`const fn = admin.mintUserToken; if (fn) await fn(...)`), implementations\n * MUST keep these methods detachment-safe — i.e. bind them to the instance so a\n * detached/destructured reference still carries `this`. See `MatomoAdmin`'s\n * constructor for the reference implementation (https://github.com/happyvertical/sdk/issues/1043).\n */\nexport interface AnalyticsAdminInterface {\n // ---------------------------------------------------------------------------\n // Site provisioning\n // ---------------------------------------------------------------------------\n\n /**\n * Create a site/property for a tenant.\n */\n createSite(options: CreateAnalyticsSiteOptions): Promise<AnalyticsSite>;\n\n /**\n * List all sites visible to the calling token.\n */\n listSites(): Promise<AnalyticsSite[]>;\n\n /**\n * Look up a site by id. Resolves to undefined when the site does not exist.\n */\n getSite(siteId: string): Promise<AnalyticsSite | undefined>;\n\n /**\n * Update an existing site in place. Optional capability — partial update:\n * only the fields supplied in the options change on the provider.\n *\n * Implementations should resolve to the post-update site as read back from\n * the provider, normalized the same way `createSite`'s result is.\n */\n updateSite?(options: UpdateAnalyticsSiteOptions): Promise<AnalyticsSite>;\n\n /**\n * Delete a site.\n */\n deleteSite(siteId: string): Promise<void>;\n\n // ---------------------------------------------------------------------------\n // User provisioning (optional capability)\n // ---------------------------------------------------------------------------\n\n /**\n * Create a user.\n */\n createUser?(options: CreateAnalyticsUserOptions): Promise<AnalyticsUser>;\n\n /**\n * Look up a user by login. Resolves to undefined when the user does not exist.\n */\n getUser?(login: string): Promise<AnalyticsUser | undefined>;\n\n /**\n * Delete a user.\n */\n deleteUser?(login: string): Promise<void>;\n\n /**\n * Grant a user access to one or more sites at the given role.\n */\n setUserAccess?(options: SetUserAccessOptions): Promise<void>;\n\n /**\n * Verify that a user has at least the requested access to a site.\n */\n verifyUserSiteAccess?(\n options: VerifyUserSiteAccessOptions,\n ): Promise<AnalyticsAccessVerificationResult>;\n\n /**\n * Verify that a token can read a site.\n */\n verifyTokenSiteAccess?(\n options: VerifyTokenSiteAccessOptions,\n ): Promise<AnalyticsAccessVerificationResult>;\n\n /**\n * Mint a per-user auth token scoped to that user's existing permissions.\n *\n * The returned token is shown-once on most providers — implementations are\n * expected to return the live value in the response and not refetch it.\n */\n mintUserToken?(options: MintUserTokenOptions): Promise<AnalyticsUserToken>;\n\n // ---------------------------------------------------------------------------\n // Health\n // ---------------------------------------------------------------------------\n\n /**\n * Probe provider reachability and auth. Always available — providers that\n * lack a public health endpoint should make a cheap authed call instead.\n */\n health(): Promise<AnalyticsHealthResult>;\n}\n\n// =============================================================================\n// Error Classes\n// =============================================================================\n\n/**\n * Base error class for analytics operations\n */\nexport class AnalyticsError extends Error {\n constructor(\n message: string,\n public code: string,\n public provider?: string,\n public propertyId?: string,\n ) {\n super(message);\n this.name = 'AnalyticsError';\n }\n}\n\n/**\n * Authentication failed\n */\nexport class AuthenticationError extends AnalyticsError {\n constructor(\n provider?: string,\n message: string = 'Authentication failed',\n code: string = 'AUTH_ERROR',\n ) {\n super(message, code, provider);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Rate limit exceeded\n */\nexport class RateLimitError extends AnalyticsError {\n public retryAfter?: number;\n\n constructor(provider?: string, retryAfter?: number) {\n super(\n `Rate limit exceeded${retryAfter ? `, retry after ${retryAfter}s` : ''}`,\n 'RATE_LIMIT',\n provider,\n );\n this.name = 'RateLimitError';\n this.retryAfter = retryAfter;\n }\n}\n\n/**\n * Property not found\n */\nexport class PropertyNotFoundError extends AnalyticsError {\n constructor(propertyId: string, provider?: string) {\n super(\n `Property not found: ${propertyId}`,\n 'PROPERTY_NOT_FOUND',\n provider,\n propertyId,\n );\n this.name = 'PropertyNotFoundError';\n }\n}\n\n/**\n * Invalid dimension specified\n */\nexport class InvalidDimensionError extends AnalyticsError {\n public dimension: string;\n\n constructor(dimension: string, provider?: string) {\n super(`Invalid dimension: ${dimension}`, 'INVALID_DIMENSION', provider);\n this.name = 'InvalidDimensionError';\n this.dimension = dimension;\n }\n}\n\n/**\n * Invalid metric specified\n */\nexport class InvalidMetricError extends AnalyticsError {\n public metric: string;\n\n constructor(metric: string, provider?: string) {\n super(`Invalid metric: ${metric}`, 'INVALID_METRIC', provider);\n this.name = 'InvalidMetricError';\n this.metric = metric;\n }\n}\n\n/**\n * Quota exceeded\n */\nexport class QuotaExceededError extends AnalyticsError {\n public quotaType?: string;\n\n constructor(provider?: string, quotaType?: string) {\n super(\n `Quota exceeded${quotaType ? `: ${quotaType}` : ''}`,\n 'QUOTA_EXCEEDED',\n provider,\n );\n this.name = 'QuotaExceededError';\n this.quotaType = quotaType;\n }\n}\n\n/**\n * Feature not supported by this provider\n */\nexport class NotSupportedError extends AnalyticsError {\n public feature: string;\n\n constructor(feature: string, provider?: string) {\n super(`Feature not supported: ${feature}`, 'NOT_SUPPORTED', provider);\n this.name = 'NotSupportedError';\n this.feature = feature;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { AnalyticsInterface, GetAnalyticsOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an analytics provider instance based on the provided options.
|
|
4
|
+
*
|
|
5
|
+
* Supports environment variable configuration using the pattern:
|
|
6
|
+
* - HAVE_ANALYTICS_TYPE → provider type ('ga4' | 'plausible' | 'matomo')
|
|
7
|
+
* - HAVE_ANALYTICS_SERVICE_ACCOUNT_KEY → path to service account JSON or JSON string
|
|
8
|
+
* - HAVE_ANALYTICS_MEASUREMENT_ID → GA4 measurement ID (G-XXXXXXX)
|
|
9
|
+
* - HAVE_ANALYTICS_API_SECRET → GA4 API secret for Measurement Protocol
|
|
10
|
+
* - HAVE_ANALYTICS_DEFAULT_PROPERTY_ID → default property ID
|
|
11
|
+
* - HAVE_ANALYTICS_API_KEY → Plausible API key
|
|
12
|
+
* - HAVE_ANALYTICS_BASE_URL → Plausible / Matomo base URL (for self-hosted)
|
|
13
|
+
* - HAVE_ANALYTICS_DEFAULT_SITE_ID → Plausible / Matomo default site ID
|
|
14
|
+
* - HAVE_ANALYTICS_TOKEN_AUTH → Matomo per-user token_auth
|
|
15
|
+
* - HAVE_ANALYTICS_TIMEOUT → request timeout in milliseconds
|
|
16
|
+
* - HAVE_ANALYTICS_MAX_RETRIES → maximum retry attempts
|
|
17
|
+
* - HAVE_ANALYTICS_CACHE_TTL → cache TTL in milliseconds
|
|
18
|
+
*
|
|
19
|
+
* User-provided options always take precedence over environment variables.
|
|
20
|
+
*
|
|
21
|
+
* @param options - Configuration options for the analytics provider
|
|
22
|
+
* @returns Promise resolving to an analytics provider instance
|
|
23
|
+
* @throws {ValidationError} When the provider type is unsupported or required options are missing
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // Create GA4 client with explicit options
|
|
28
|
+
* const ga4 = await getAnalytics({
|
|
29
|
+
* type: 'ga4',
|
|
30
|
+
* serviceAccountKey: '/path/to/service-account.json',
|
|
31
|
+
* measurementId: 'G-XXXXXXXXXX',
|
|
32
|
+
* apiSecret: 'your-api-secret'
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* // Create Plausible client
|
|
36
|
+
* const plausible = await getAnalytics({
|
|
37
|
+
* type: 'plausible',
|
|
38
|
+
* apiKey: 'your-api-key',
|
|
39
|
+
* baseUrl: 'https://plausible.io' // or self-hosted URL
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* // Use environment variables
|
|
43
|
+
* // Set: HAVE_ANALYTICS_TYPE=ga4, HAVE_ANALYTICS_SERVICE_ACCOUNT_KEY=/path/to/key.json, etc.
|
|
44
|
+
* const client = await getAnalytics({ type: 'ga4' });
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function getAnalytics(options: GetAnalyticsOptions): Promise<AnalyticsInterface>;
|
|
48
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/shared/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EACV,kBAAkB,EAElB,mBAAmB,EAGpB,MAAM,YAAY,CAAC;AA2BpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CA2C7B"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { AnalyticsCapabilities, AnalyticsInterface, ConfigOptions, CreateDataStreamOptions, CreatePropertyOptions, CustomDimension, CustomDimensionOptions, CustomMetric, CustomMetricOptions, DataStream, DimensionMetadata, GA4Options, KeyEvent, KeyEventOptions, ListPropertiesOptions, MetricMetadata, PageviewEvent, Property, RealtimeReportOptions, ReportOptions, ReportResult, SnippetOptions, TrackEvent, TrackingSnippet, UpdatePropertyOptions } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Google Analytics 4 provider
|
|
4
|
+
*/
|
|
5
|
+
export declare class GA4Provider implements AnalyticsInterface {
|
|
6
|
+
private adminClient;
|
|
7
|
+
private dataClient;
|
|
8
|
+
private options;
|
|
9
|
+
private credentials;
|
|
10
|
+
constructor(options: GA4Options);
|
|
11
|
+
/**
|
|
12
|
+
* Initialize Google API clients with service account credentials
|
|
13
|
+
*/
|
|
14
|
+
private ensureClients;
|
|
15
|
+
/**
|
|
16
|
+
* Normalize property ID to numeric format
|
|
17
|
+
*/
|
|
18
|
+
private normalizePropertyId;
|
|
19
|
+
/**
|
|
20
|
+
* Get full property resource name
|
|
21
|
+
*/
|
|
22
|
+
private getPropertyName;
|
|
23
|
+
/**
|
|
24
|
+
* Map a Google Analytics property resource to the public Property shape
|
|
25
|
+
*/
|
|
26
|
+
private mapProperty;
|
|
27
|
+
/**
|
|
28
|
+
* Hydrate discovered properties without firing unbounded concurrent requests
|
|
29
|
+
*/
|
|
30
|
+
private hydrateProperties;
|
|
31
|
+
/**
|
|
32
|
+
* Map Google API errors to our error types
|
|
33
|
+
*/
|
|
34
|
+
private mapError;
|
|
35
|
+
createProperty(options: CreatePropertyOptions): Promise<Property>;
|
|
36
|
+
listProperties(options?: ListPropertiesOptions): Promise<Property[]>;
|
|
37
|
+
getProperty(propertyId: string): Promise<Property>;
|
|
38
|
+
updateProperty(propertyId: string, data: UpdatePropertyOptions): Promise<Property>;
|
|
39
|
+
deleteProperty(propertyId: string): Promise<void>;
|
|
40
|
+
getDataStreams(propertyId: string): Promise<DataStream[]>;
|
|
41
|
+
createDataStream(propertyId: string, options: CreateDataStreamOptions): Promise<DataStream>;
|
|
42
|
+
deleteDataStream(propertyId: string, streamId: string): Promise<void>;
|
|
43
|
+
getCustomDimensions(propertyId: string): Promise<CustomDimension[]>;
|
|
44
|
+
createCustomDimension(propertyId: string, options: CustomDimensionOptions): Promise<CustomDimension>;
|
|
45
|
+
archiveCustomDimension(propertyId: string, dimensionId: string): Promise<void>;
|
|
46
|
+
getCustomMetrics(propertyId: string): Promise<CustomMetric[]>;
|
|
47
|
+
createCustomMetric(propertyId: string, options: CustomMetricOptions): Promise<CustomMetric>;
|
|
48
|
+
archiveCustomMetric(propertyId: string, metricId: string): Promise<void>;
|
|
49
|
+
getKeyEvents(propertyId: string): Promise<KeyEvent[]>;
|
|
50
|
+
createKeyEvent(propertyId: string, options: KeyEventOptions): Promise<KeyEvent>;
|
|
51
|
+
deleteKeyEvent(propertyId: string, eventId: string): Promise<void>;
|
|
52
|
+
runReport(propertyId: string, options: ReportOptions): Promise<ReportResult>;
|
|
53
|
+
runRealtimeReport(propertyId: string, options?: RealtimeReportOptions): Promise<ReportResult>;
|
|
54
|
+
getMetrics(propertyId: string): Promise<MetricMetadata[]>;
|
|
55
|
+
getDimensions(propertyId: string): Promise<DimensionMetadata[]>;
|
|
56
|
+
track(event: TrackEvent): Promise<void>;
|
|
57
|
+
trackPageview(pageview: PageviewEvent): Promise<void>;
|
|
58
|
+
trackBatch(events: TrackEvent[]): Promise<void>;
|
|
59
|
+
identify(userId: string, traits?: Record<string, unknown>): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Generate a random client ID for Measurement Protocol
|
|
62
|
+
*/
|
|
63
|
+
private generateClientId;
|
|
64
|
+
generateTrackingSnippet(propertyId: string, options?: SnippetOptions): TrackingSnippet;
|
|
65
|
+
generateConfig(propertyId: string, options?: ConfigOptions): Record<string, unknown>;
|
|
66
|
+
getCapabilities(): Promise<AnalyticsCapabilities>;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=ga4.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ga4.d.ts","sourceRoot":"","sources":["../../../src/shared/providers/ga4.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { AnalyticsAccessVerificationResult, AnalyticsAdminInterface, AnalyticsHealthResult, AnalyticsSite, AnalyticsUser, AnalyticsUserToken, CreateAnalyticsSiteOptions, CreateAnalyticsUserOptions, MintUserTokenOptions, SetUserAccessOptions, UpdateAnalyticsSiteOptions, VerifyTokenSiteAccessOptions, VerifyUserSiteAccessOptions } from '../types.js';
|
|
2
|
+
export interface MatomoAdminTransportOptions {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
tokenAuth: string;
|
|
5
|
+
timeout?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Normalize a Matomo base URL: trim whitespace, strip trailing slashes, and
|
|
9
|
+
* remove a trailing `/index.php` if the caller provided one. Returns the host
|
|
10
|
+
* root so callers can append `/index.php` themselves.
|
|
11
|
+
*/
|
|
12
|
+
export declare function normalizeMatomoBaseUrl(value: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* POST a `module=API&method=...` form to Matomo and return the parsed JSON.
|
|
15
|
+
*
|
|
16
|
+
* Matomo accepts `application/x-www-form-urlencoded` — we use `URLSearchParams`
|
|
17
|
+
* so array values like `idSites[]=1&idSites[]=2` are handled by the runtime.
|
|
18
|
+
*/
|
|
19
|
+
export declare class MatomoAdminTransport {
|
|
20
|
+
private readonly baseUrl;
|
|
21
|
+
private readonly tokenAuth;
|
|
22
|
+
private readonly timeout?;
|
|
23
|
+
constructor(options: MatomoAdminTransportOptions);
|
|
24
|
+
/**
|
|
25
|
+
* Call a Matomo API method by name (e.g. `SitesManager.addSite`).
|
|
26
|
+
*
|
|
27
|
+
* `params` becomes the request body. Array values are encoded as
|
|
28
|
+
* `key[]=...&key[]=...`. Undefined and null values are dropped. The
|
|
29
|
+
* reserved keys `module`, `method`, `format`, and `token_auth` are
|
|
30
|
+
* controlled by the transport — any caller-supplied value for those
|
|
31
|
+
* keys is silently ignored so they cannot override the dispatch or
|
|
32
|
+
* the response format.
|
|
33
|
+
*/
|
|
34
|
+
call<T = unknown>(method: string, params: Record<string, string | number | boolean | undefined | string[] | number[]>): Promise<T>;
|
|
35
|
+
}
|
|
36
|
+
export declare class MatomoAdmin implements AnalyticsAdminInterface {
|
|
37
|
+
private readonly baseUrl;
|
|
38
|
+
private readonly timeout?;
|
|
39
|
+
private readonly transport;
|
|
40
|
+
constructor(options: MatomoAdminTransportOptions);
|
|
41
|
+
private cloneTransportWithToken;
|
|
42
|
+
createSite(options: CreateAnalyticsSiteOptions): Promise<AnalyticsSite>;
|
|
43
|
+
listSites(): Promise<AnalyticsSite[]>;
|
|
44
|
+
getSite(siteId: string): Promise<AnalyticsSite | undefined>;
|
|
45
|
+
updateSite(options: UpdateAnalyticsSiteOptions): Promise<AnalyticsSite>;
|
|
46
|
+
deleteSite(siteId: string): Promise<void>;
|
|
47
|
+
createUser(options: CreateAnalyticsUserOptions): Promise<AnalyticsUser>;
|
|
48
|
+
getUser(login: string): Promise<AnalyticsUser | undefined>;
|
|
49
|
+
deleteUser(login: string): Promise<void>;
|
|
50
|
+
setUserAccess(options: SetUserAccessOptions): Promise<void>;
|
|
51
|
+
verifyUserSiteAccess(options: VerifyUserSiteAccessOptions): Promise<AnalyticsAccessVerificationResult>;
|
|
52
|
+
verifyTokenSiteAccess(options: VerifyTokenSiteAccessOptions): Promise<AnalyticsAccessVerificationResult>;
|
|
53
|
+
mintUserToken(options: MintUserTokenOptions): Promise<AnalyticsUserToken>;
|
|
54
|
+
health(): Promise<AnalyticsHealthResult>;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=matomo-admin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matomo-admin.d.ts","sourceRoot":"","sources":["../../../src/shared/providers/matomo-admin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAEL,KAAK,iCAAiC,EACtC,KAAK,uBAAuB,EAE5B,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EAEvB,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EACjC,MAAM,aAAa,CAAC;AAIrB,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAsBD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAU5D;AAsCD;;;;;GAKG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;gBAEtB,OAAO,EAAE,2BAA2B;IAahD;;;;;;;;;OASG;IACG,IAAI,CAAC,CAAC,GAAG,OAAO,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,CACZ,MAAM,EACN,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAC5D,GACA,OAAO,CAAC,CAAC,CAAC;CAsEd;AA+GD,qBAAa,WAAY,YAAW,uBAAuB;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;gBAErC,OAAO,EAAE,2BAA2B;IAgChD,OAAO,CAAC,uBAAuB;IAYzB,UAAU,CACd,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,aAAa,CAAC;IA6CnB,SAAS,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IASrC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAmB3D,UAAU,CACd,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,aAAa,CAAC;IAqCnB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzC,UAAU,CACd,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,aAAa,CAAC;IA2BnB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IA2B1D,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxC,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB3D,oBAAoB,CACxB,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,iCAAiC,CAAC;IAqDvC,qBAAqB,CACzB,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,iCAAiC,CAAC;IAwDvC,aAAa,CACjB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,kBAAkB,CAAC;IAgDxB,MAAM,IAAI,OAAO,CAAC,qBAAqB,CAAC;CAiB/C"}
|