@power-seo/tracking 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +384 -0
- package/dist/index.cjs +379 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +26 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +367 -0
- package/dist/index.js.map +1 -0
- package/dist/react.cjs +132 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +38 -0
- package/dist/react.d.ts +38 -0
- package/dist/react.js +129 -0
- package/dist/react.js.map +1 -0
- package/dist/types-DFyKCGgf.d.cts +180 -0
- package/dist/types-DFyKCGgf.d.ts +180 -0
- package/package.json +77 -0
package/dist/react.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { createElement, useState, useEffect, useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
// src/react.ts
|
|
4
|
+
function AnalyticsScript({ scripts, consent }) {
|
|
5
|
+
const loadable = scripts.filter((s) => s.shouldLoad(consent));
|
|
6
|
+
if (loadable.length === 0) return null;
|
|
7
|
+
return createElement(
|
|
8
|
+
"div",
|
|
9
|
+
{ "data-testid": "analytics-scripts" },
|
|
10
|
+
...loadable.map(
|
|
11
|
+
(script) => script.src ? createElement("script", {
|
|
12
|
+
key: script.id,
|
|
13
|
+
src: script.src,
|
|
14
|
+
async: script.async ?? false,
|
|
15
|
+
defer: script.defer ?? false,
|
|
16
|
+
...Object.fromEntries(
|
|
17
|
+
Object.entries(script.attributes ?? {}).map(([k, v]) => [k, v])
|
|
18
|
+
)
|
|
19
|
+
}) : createElement("script", {
|
|
20
|
+
key: script.id,
|
|
21
|
+
dangerouslySetInnerHTML: { __html: script.innerHTML ?? "" }
|
|
22
|
+
})
|
|
23
|
+
)
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
function ConsentBanner({ manager, privacyPolicyUrl }) {
|
|
27
|
+
const [state, setState] = useState(manager.getState());
|
|
28
|
+
const [visible, setVisible] = useState(!state.analytics);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
return manager.onChange((newState) => {
|
|
31
|
+
setState(newState);
|
|
32
|
+
});
|
|
33
|
+
}, [manager]);
|
|
34
|
+
const handleAcceptAll = useCallback(() => {
|
|
35
|
+
manager.grantAll();
|
|
36
|
+
setVisible(false);
|
|
37
|
+
}, [manager]);
|
|
38
|
+
const handleRejectAll = useCallback(() => {
|
|
39
|
+
manager.revokeAll();
|
|
40
|
+
setVisible(false);
|
|
41
|
+
}, [manager]);
|
|
42
|
+
if (!visible) return null;
|
|
43
|
+
return createElement(
|
|
44
|
+
"div",
|
|
45
|
+
{
|
|
46
|
+
"data-testid": "consent-banner",
|
|
47
|
+
role: "dialog",
|
|
48
|
+
"aria-label": "Cookie consent",
|
|
49
|
+
style: {
|
|
50
|
+
position: "fixed",
|
|
51
|
+
bottom: 0,
|
|
52
|
+
left: 0,
|
|
53
|
+
right: 0,
|
|
54
|
+
padding: "16px 24px",
|
|
55
|
+
backgroundColor: "#fff",
|
|
56
|
+
borderTop: "1px solid #e0e0e0",
|
|
57
|
+
boxShadow: "0 -2px 10px rgba(0,0,0,0.1)",
|
|
58
|
+
display: "flex",
|
|
59
|
+
justifyContent: "space-between",
|
|
60
|
+
alignItems: "center",
|
|
61
|
+
gap: "16px",
|
|
62
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
63
|
+
fontSize: "14px",
|
|
64
|
+
zIndex: 9999
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
createElement(
|
|
68
|
+
"div",
|
|
69
|
+
{ style: { flex: 1 } },
|
|
70
|
+
createElement(
|
|
71
|
+
"p",
|
|
72
|
+
{ style: { margin: 0, color: "#333" } },
|
|
73
|
+
"We use cookies to improve your experience and analyze site traffic.",
|
|
74
|
+
privacyPolicyUrl ? createElement(
|
|
75
|
+
"a",
|
|
76
|
+
{
|
|
77
|
+
href: privacyPolicyUrl,
|
|
78
|
+
style: { marginLeft: "4px", color: "#1a73e8", textDecoration: "underline" },
|
|
79
|
+
target: "_blank",
|
|
80
|
+
rel: "noopener noreferrer"
|
|
81
|
+
},
|
|
82
|
+
"Privacy Policy"
|
|
83
|
+
) : null
|
|
84
|
+
)
|
|
85
|
+
),
|
|
86
|
+
createElement(
|
|
87
|
+
"div",
|
|
88
|
+
{ style: { display: "flex", gap: "8px", flexShrink: 0 } },
|
|
89
|
+
createElement(
|
|
90
|
+
"button",
|
|
91
|
+
{
|
|
92
|
+
"data-testid": "consent-reject",
|
|
93
|
+
onClick: handleRejectAll,
|
|
94
|
+
style: {
|
|
95
|
+
padding: "8px 16px",
|
|
96
|
+
border: "1px solid #dadce0",
|
|
97
|
+
borderRadius: "4px",
|
|
98
|
+
backgroundColor: "#fff",
|
|
99
|
+
cursor: "pointer",
|
|
100
|
+
fontSize: "13px",
|
|
101
|
+
color: "#333"
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"Reject All"
|
|
105
|
+
),
|
|
106
|
+
createElement(
|
|
107
|
+
"button",
|
|
108
|
+
{
|
|
109
|
+
"data-testid": "consent-accept",
|
|
110
|
+
onClick: handleAcceptAll,
|
|
111
|
+
style: {
|
|
112
|
+
padding: "8px 16px",
|
|
113
|
+
border: "none",
|
|
114
|
+
borderRadius: "4px",
|
|
115
|
+
backgroundColor: "#1a73e8",
|
|
116
|
+
color: "#fff",
|
|
117
|
+
cursor: "pointer",
|
|
118
|
+
fontSize: "13px"
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"Accept All"
|
|
122
|
+
)
|
|
123
|
+
)
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export { AnalyticsScript, ConsentBanner };
|
|
128
|
+
//# sourceMappingURL=react.js.map
|
|
129
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react.ts"],"names":[],"mappings":"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","file":"react.js","sourcesContent":["// ============================================================================\r\n// @power-seo/tracking — React Components\r\n// ============================================================================\r\n\r\nimport { createElement, useEffect, useState, useCallback } from 'react';\r\nimport type { ScriptConfig, ConsentManager, ConsentState } from './types.js';\r\n\r\n// --- AnalyticsScript ---\r\n\r\nexport interface AnalyticsScriptProps {\r\n scripts: ScriptConfig[];\r\n consent: ConsentState;\r\n}\r\n\r\nexport function AnalyticsScript({ scripts, consent }: AnalyticsScriptProps) {\r\n const loadable = scripts.filter((s) => s.shouldLoad(consent));\r\n\r\n if (loadable.length === 0) return null;\r\n\r\n return createElement(\r\n 'div',\r\n { 'data-testid': 'analytics-scripts' },\r\n ...loadable.map((script) =>\r\n script.src\r\n ? createElement('script', {\r\n key: script.id,\r\n src: script.src,\r\n async: script.async ?? false,\r\n defer: script.defer ?? false,\r\n ...Object.fromEntries(\r\n Object.entries(script.attributes ?? {}).map(([k, v]) => [k, v]),\r\n ),\r\n })\r\n : createElement('script', {\r\n key: script.id,\r\n dangerouslySetInnerHTML: { __html: script.innerHTML ?? '' },\r\n }),\r\n ),\r\n );\r\n}\r\n\r\n// --- ConsentBanner ---\r\n\r\nexport interface ConsentBannerProps {\r\n manager: ConsentManager;\r\n privacyPolicyUrl?: string;\r\n}\r\n\r\nexport function ConsentBanner({ manager, privacyPolicyUrl }: ConsentBannerProps) {\r\n const [state, setState] = useState<ConsentState>(manager.getState());\r\n const [visible, setVisible] = useState(!state.analytics);\r\n\r\n useEffect(() => {\r\n return manager.onChange((newState) => {\r\n setState(newState);\r\n });\r\n }, [manager]);\r\n\r\n const handleAcceptAll = useCallback(() => {\r\n manager.grantAll();\r\n setVisible(false);\r\n }, [manager]);\r\n\r\n const handleRejectAll = useCallback(() => {\r\n manager.revokeAll();\r\n setVisible(false);\r\n }, [manager]);\r\n\r\n if (!visible) return null;\r\n\r\n return createElement(\r\n 'div',\r\n {\r\n 'data-testid': 'consent-banner',\r\n role: 'dialog',\r\n 'aria-label': 'Cookie consent',\r\n style: {\r\n position: 'fixed',\r\n bottom: 0,\r\n left: 0,\r\n right: 0,\r\n padding: '16px 24px',\r\n backgroundColor: '#fff',\r\n borderTop: '1px solid #e0e0e0',\r\n boxShadow: '0 -2px 10px rgba(0,0,0,0.1)',\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n alignItems: 'center',\r\n gap: '16px',\r\n fontFamily: 'system-ui, -apple-system, sans-serif',\r\n fontSize: '14px',\r\n zIndex: 9999,\r\n },\r\n },\r\n createElement(\r\n 'div',\r\n { style: { flex: 1 } },\r\n createElement(\r\n 'p',\r\n { style: { margin: 0, color: '#333' } },\r\n 'We use cookies to improve your experience and analyze site traffic.',\r\n privacyPolicyUrl\r\n ? createElement(\r\n 'a',\r\n {\r\n href: privacyPolicyUrl,\r\n style: { marginLeft: '4px', color: '#1a73e8', textDecoration: 'underline' },\r\n target: '_blank',\r\n rel: 'noopener noreferrer',\r\n },\r\n 'Privacy Policy',\r\n )\r\n : null,\r\n ),\r\n ),\r\n createElement(\r\n 'div',\r\n { style: { display: 'flex', gap: '8px', flexShrink: 0 } },\r\n createElement(\r\n 'button',\r\n {\r\n 'data-testid': 'consent-reject',\r\n onClick: handleRejectAll,\r\n style: {\r\n padding: '8px 16px',\r\n border: '1px solid #dadce0',\r\n borderRadius: '4px',\r\n backgroundColor: '#fff',\r\n cursor: 'pointer',\r\n fontSize: '13px',\r\n color: '#333',\r\n },\r\n },\r\n 'Reject All',\r\n ),\r\n createElement(\r\n 'button',\r\n {\r\n 'data-testid': 'consent-accept',\r\n onClick: handleAcceptAll,\r\n style: {\r\n padding: '8px 16px',\r\n border: 'none',\r\n borderRadius: '4px',\r\n backgroundColor: '#1a73e8',\r\n color: '#fff',\r\n cursor: 'pointer',\r\n fontSize: '13px',\r\n },\r\n },\r\n 'Accept All',\r\n ),\r\n ),\r\n );\r\n}\r\n"]}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
type ConsentCategory = 'necessary' | 'analytics' | 'marketing' | 'preferences';
|
|
2
|
+
interface ScriptConfig {
|
|
3
|
+
id: string;
|
|
4
|
+
src?: string;
|
|
5
|
+
innerHTML?: string;
|
|
6
|
+
async?: boolean;
|
|
7
|
+
defer?: boolean;
|
|
8
|
+
consentCategory: ConsentCategory;
|
|
9
|
+
attributes?: Record<string, string>;
|
|
10
|
+
shouldLoad: (consent: ConsentState) => boolean;
|
|
11
|
+
}
|
|
12
|
+
interface ConsentState {
|
|
13
|
+
necessary: boolean;
|
|
14
|
+
analytics: boolean;
|
|
15
|
+
marketing: boolean;
|
|
16
|
+
preferences: boolean;
|
|
17
|
+
}
|
|
18
|
+
interface ConsentManager {
|
|
19
|
+
getState: () => ConsentState;
|
|
20
|
+
grant: (category: ConsentCategory) => void;
|
|
21
|
+
revoke: (category: ConsentCategory) => void;
|
|
22
|
+
grantAll: () => void;
|
|
23
|
+
revokeAll: () => void;
|
|
24
|
+
isGranted: (category: ConsentCategory) => boolean;
|
|
25
|
+
onChange: (callback: ConsentChangeCallback) => () => void;
|
|
26
|
+
}
|
|
27
|
+
type ConsentChangeCallback = (state: ConsentState) => void;
|
|
28
|
+
interface GA4Config {
|
|
29
|
+
measurementId: string;
|
|
30
|
+
consentModeV2?: boolean;
|
|
31
|
+
anonymizeIp?: boolean;
|
|
32
|
+
sendPageView?: boolean;
|
|
33
|
+
}
|
|
34
|
+
interface GA4ReportRequest {
|
|
35
|
+
startDate: string;
|
|
36
|
+
endDate: string;
|
|
37
|
+
metrics: string[];
|
|
38
|
+
dimensions?: string[];
|
|
39
|
+
limit?: number;
|
|
40
|
+
}
|
|
41
|
+
interface GA4ReportRow {
|
|
42
|
+
dimensions: string[];
|
|
43
|
+
metrics: number[];
|
|
44
|
+
}
|
|
45
|
+
interface GA4ReportResponse {
|
|
46
|
+
rows: GA4ReportRow[];
|
|
47
|
+
rowCount: number;
|
|
48
|
+
metadata?: {
|
|
49
|
+
metricHeaders: Array<{
|
|
50
|
+
name: string;
|
|
51
|
+
type: string;
|
|
52
|
+
}>;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
interface GA4Client {
|
|
56
|
+
queryReport: (propertyId: string, request: GA4ReportRequest) => Promise<GA4ReportResponse>;
|
|
57
|
+
getRealtimeReport: (propertyId: string, metrics: string[]) => Promise<GA4ReportResponse>;
|
|
58
|
+
getMetadata: (propertyId: string) => Promise<GA4Metadata>;
|
|
59
|
+
}
|
|
60
|
+
interface GA4Metadata {
|
|
61
|
+
dimensions: Array<{
|
|
62
|
+
apiName: string;
|
|
63
|
+
uiName: string;
|
|
64
|
+
description: string;
|
|
65
|
+
}>;
|
|
66
|
+
metrics: Array<{
|
|
67
|
+
apiName: string;
|
|
68
|
+
uiName: string;
|
|
69
|
+
description: string;
|
|
70
|
+
type: string;
|
|
71
|
+
}>;
|
|
72
|
+
}
|
|
73
|
+
interface ClarityConfig {
|
|
74
|
+
projectId: string;
|
|
75
|
+
}
|
|
76
|
+
interface ClarityProject {
|
|
77
|
+
id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
url: string;
|
|
80
|
+
}
|
|
81
|
+
interface ClarityInsight {
|
|
82
|
+
type: string;
|
|
83
|
+
value: number;
|
|
84
|
+
label: string;
|
|
85
|
+
trend: 'up' | 'down' | 'stable';
|
|
86
|
+
}
|
|
87
|
+
interface ClarityHeatmapData {
|
|
88
|
+
url: string;
|
|
89
|
+
clicks: Array<{
|
|
90
|
+
x: number;
|
|
91
|
+
y: number;
|
|
92
|
+
count: number;
|
|
93
|
+
}>;
|
|
94
|
+
scrollDepth: number[];
|
|
95
|
+
}
|
|
96
|
+
interface ClarityClient {
|
|
97
|
+
getProjects: () => Promise<ClarityProject[]>;
|
|
98
|
+
getInsights: (projectId: string) => Promise<ClarityInsight[]>;
|
|
99
|
+
getHeatmapData: (projectId: string, url: string) => Promise<ClarityHeatmapData>;
|
|
100
|
+
}
|
|
101
|
+
interface PostHogConfig {
|
|
102
|
+
apiKey: string;
|
|
103
|
+
host?: string;
|
|
104
|
+
}
|
|
105
|
+
interface PostHogEvent {
|
|
106
|
+
event: string;
|
|
107
|
+
timestamp: string;
|
|
108
|
+
properties: Record<string, unknown>;
|
|
109
|
+
}
|
|
110
|
+
interface PostHogTrendResult {
|
|
111
|
+
label: string;
|
|
112
|
+
data: number[];
|
|
113
|
+
days: string[];
|
|
114
|
+
}
|
|
115
|
+
interface PostHogFunnelStep {
|
|
116
|
+
name: string;
|
|
117
|
+
count: number;
|
|
118
|
+
conversionRate: number;
|
|
119
|
+
}
|
|
120
|
+
interface PostHogClient {
|
|
121
|
+
queryEvents: (projectId: string, event: string, limit?: number) => Promise<PostHogEvent[]>;
|
|
122
|
+
getTrends: (projectId: string, events: string[], days?: number) => Promise<PostHogTrendResult[]>;
|
|
123
|
+
getFunnels: (projectId: string, steps: string[]) => Promise<PostHogFunnelStep[]>;
|
|
124
|
+
}
|
|
125
|
+
interface PlausibleConfig {
|
|
126
|
+
domain: string;
|
|
127
|
+
selfHostedUrl?: string;
|
|
128
|
+
}
|
|
129
|
+
interface PlausibleTimeseriesPoint {
|
|
130
|
+
date: string;
|
|
131
|
+
visitors: number;
|
|
132
|
+
pageviews: number;
|
|
133
|
+
bounceRate: number;
|
|
134
|
+
visitDuration: number;
|
|
135
|
+
}
|
|
136
|
+
interface PlausibleBreakdownEntry {
|
|
137
|
+
property: string;
|
|
138
|
+
visitors: number;
|
|
139
|
+
pageviews: number;
|
|
140
|
+
bounceRate: number;
|
|
141
|
+
}
|
|
142
|
+
interface PlausibleAggregateResult {
|
|
143
|
+
visitors: number;
|
|
144
|
+
pageviews: number;
|
|
145
|
+
bounceRate: number;
|
|
146
|
+
visitDuration: number;
|
|
147
|
+
events: number;
|
|
148
|
+
}
|
|
149
|
+
interface PlausibleClient {
|
|
150
|
+
getTimeseries: (siteId: string, period?: string) => Promise<PlausibleTimeseriesPoint[]>;
|
|
151
|
+
getBreakdown: (siteId: string, property: string, period?: string) => Promise<PlausibleBreakdownEntry[]>;
|
|
152
|
+
getAggregate: (siteId: string, period?: string) => Promise<PlausibleAggregateResult>;
|
|
153
|
+
}
|
|
154
|
+
interface FathomConfig {
|
|
155
|
+
siteId: string;
|
|
156
|
+
}
|
|
157
|
+
interface FathomSite {
|
|
158
|
+
id: string;
|
|
159
|
+
name: string;
|
|
160
|
+
sharing: string;
|
|
161
|
+
}
|
|
162
|
+
interface FathomPageview {
|
|
163
|
+
pathname: string;
|
|
164
|
+
pageviews: number;
|
|
165
|
+
visitors: number;
|
|
166
|
+
avgDuration: number;
|
|
167
|
+
bounceRate: number;
|
|
168
|
+
}
|
|
169
|
+
interface FathomReferrer {
|
|
170
|
+
source: string;
|
|
171
|
+
visitors: number;
|
|
172
|
+
pageviews: number;
|
|
173
|
+
}
|
|
174
|
+
interface FathomClient {
|
|
175
|
+
getSites: () => Promise<FathomSite[]>;
|
|
176
|
+
getPageviews: (siteId: string, period?: string) => Promise<FathomPageview[]>;
|
|
177
|
+
getReferrers: (siteId: string, period?: string) => Promise<FathomReferrer[]>;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export type { ConsentState as C, FathomConfig as F, GA4Config as G, PostHogConfig as P, ScriptConfig as S, ConsentManager as a, ClarityConfig as b, PlausibleConfig as c, GA4Client as d, ClarityClient as e, PostHogClient as f, PlausibleClient as g, FathomClient as h, ClarityHeatmapData as i, ClarityInsight as j, ClarityProject as k, ConsentCategory as l, ConsentChangeCallback as m, FathomPageview as n, FathomReferrer as o, FathomSite as p, GA4Metadata as q, GA4ReportRequest as r, GA4ReportResponse as s, GA4ReportRow as t, PlausibleAggregateResult as u, PlausibleBreakdownEntry as v, PlausibleTimeseriesPoint as w, PostHogEvent as x, PostHogFunnelStep as y, PostHogTrendResult as z };
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
type ConsentCategory = 'necessary' | 'analytics' | 'marketing' | 'preferences';
|
|
2
|
+
interface ScriptConfig {
|
|
3
|
+
id: string;
|
|
4
|
+
src?: string;
|
|
5
|
+
innerHTML?: string;
|
|
6
|
+
async?: boolean;
|
|
7
|
+
defer?: boolean;
|
|
8
|
+
consentCategory: ConsentCategory;
|
|
9
|
+
attributes?: Record<string, string>;
|
|
10
|
+
shouldLoad: (consent: ConsentState) => boolean;
|
|
11
|
+
}
|
|
12
|
+
interface ConsentState {
|
|
13
|
+
necessary: boolean;
|
|
14
|
+
analytics: boolean;
|
|
15
|
+
marketing: boolean;
|
|
16
|
+
preferences: boolean;
|
|
17
|
+
}
|
|
18
|
+
interface ConsentManager {
|
|
19
|
+
getState: () => ConsentState;
|
|
20
|
+
grant: (category: ConsentCategory) => void;
|
|
21
|
+
revoke: (category: ConsentCategory) => void;
|
|
22
|
+
grantAll: () => void;
|
|
23
|
+
revokeAll: () => void;
|
|
24
|
+
isGranted: (category: ConsentCategory) => boolean;
|
|
25
|
+
onChange: (callback: ConsentChangeCallback) => () => void;
|
|
26
|
+
}
|
|
27
|
+
type ConsentChangeCallback = (state: ConsentState) => void;
|
|
28
|
+
interface GA4Config {
|
|
29
|
+
measurementId: string;
|
|
30
|
+
consentModeV2?: boolean;
|
|
31
|
+
anonymizeIp?: boolean;
|
|
32
|
+
sendPageView?: boolean;
|
|
33
|
+
}
|
|
34
|
+
interface GA4ReportRequest {
|
|
35
|
+
startDate: string;
|
|
36
|
+
endDate: string;
|
|
37
|
+
metrics: string[];
|
|
38
|
+
dimensions?: string[];
|
|
39
|
+
limit?: number;
|
|
40
|
+
}
|
|
41
|
+
interface GA4ReportRow {
|
|
42
|
+
dimensions: string[];
|
|
43
|
+
metrics: number[];
|
|
44
|
+
}
|
|
45
|
+
interface GA4ReportResponse {
|
|
46
|
+
rows: GA4ReportRow[];
|
|
47
|
+
rowCount: number;
|
|
48
|
+
metadata?: {
|
|
49
|
+
metricHeaders: Array<{
|
|
50
|
+
name: string;
|
|
51
|
+
type: string;
|
|
52
|
+
}>;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
interface GA4Client {
|
|
56
|
+
queryReport: (propertyId: string, request: GA4ReportRequest) => Promise<GA4ReportResponse>;
|
|
57
|
+
getRealtimeReport: (propertyId: string, metrics: string[]) => Promise<GA4ReportResponse>;
|
|
58
|
+
getMetadata: (propertyId: string) => Promise<GA4Metadata>;
|
|
59
|
+
}
|
|
60
|
+
interface GA4Metadata {
|
|
61
|
+
dimensions: Array<{
|
|
62
|
+
apiName: string;
|
|
63
|
+
uiName: string;
|
|
64
|
+
description: string;
|
|
65
|
+
}>;
|
|
66
|
+
metrics: Array<{
|
|
67
|
+
apiName: string;
|
|
68
|
+
uiName: string;
|
|
69
|
+
description: string;
|
|
70
|
+
type: string;
|
|
71
|
+
}>;
|
|
72
|
+
}
|
|
73
|
+
interface ClarityConfig {
|
|
74
|
+
projectId: string;
|
|
75
|
+
}
|
|
76
|
+
interface ClarityProject {
|
|
77
|
+
id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
url: string;
|
|
80
|
+
}
|
|
81
|
+
interface ClarityInsight {
|
|
82
|
+
type: string;
|
|
83
|
+
value: number;
|
|
84
|
+
label: string;
|
|
85
|
+
trend: 'up' | 'down' | 'stable';
|
|
86
|
+
}
|
|
87
|
+
interface ClarityHeatmapData {
|
|
88
|
+
url: string;
|
|
89
|
+
clicks: Array<{
|
|
90
|
+
x: number;
|
|
91
|
+
y: number;
|
|
92
|
+
count: number;
|
|
93
|
+
}>;
|
|
94
|
+
scrollDepth: number[];
|
|
95
|
+
}
|
|
96
|
+
interface ClarityClient {
|
|
97
|
+
getProjects: () => Promise<ClarityProject[]>;
|
|
98
|
+
getInsights: (projectId: string) => Promise<ClarityInsight[]>;
|
|
99
|
+
getHeatmapData: (projectId: string, url: string) => Promise<ClarityHeatmapData>;
|
|
100
|
+
}
|
|
101
|
+
interface PostHogConfig {
|
|
102
|
+
apiKey: string;
|
|
103
|
+
host?: string;
|
|
104
|
+
}
|
|
105
|
+
interface PostHogEvent {
|
|
106
|
+
event: string;
|
|
107
|
+
timestamp: string;
|
|
108
|
+
properties: Record<string, unknown>;
|
|
109
|
+
}
|
|
110
|
+
interface PostHogTrendResult {
|
|
111
|
+
label: string;
|
|
112
|
+
data: number[];
|
|
113
|
+
days: string[];
|
|
114
|
+
}
|
|
115
|
+
interface PostHogFunnelStep {
|
|
116
|
+
name: string;
|
|
117
|
+
count: number;
|
|
118
|
+
conversionRate: number;
|
|
119
|
+
}
|
|
120
|
+
interface PostHogClient {
|
|
121
|
+
queryEvents: (projectId: string, event: string, limit?: number) => Promise<PostHogEvent[]>;
|
|
122
|
+
getTrends: (projectId: string, events: string[], days?: number) => Promise<PostHogTrendResult[]>;
|
|
123
|
+
getFunnels: (projectId: string, steps: string[]) => Promise<PostHogFunnelStep[]>;
|
|
124
|
+
}
|
|
125
|
+
interface PlausibleConfig {
|
|
126
|
+
domain: string;
|
|
127
|
+
selfHostedUrl?: string;
|
|
128
|
+
}
|
|
129
|
+
interface PlausibleTimeseriesPoint {
|
|
130
|
+
date: string;
|
|
131
|
+
visitors: number;
|
|
132
|
+
pageviews: number;
|
|
133
|
+
bounceRate: number;
|
|
134
|
+
visitDuration: number;
|
|
135
|
+
}
|
|
136
|
+
interface PlausibleBreakdownEntry {
|
|
137
|
+
property: string;
|
|
138
|
+
visitors: number;
|
|
139
|
+
pageviews: number;
|
|
140
|
+
bounceRate: number;
|
|
141
|
+
}
|
|
142
|
+
interface PlausibleAggregateResult {
|
|
143
|
+
visitors: number;
|
|
144
|
+
pageviews: number;
|
|
145
|
+
bounceRate: number;
|
|
146
|
+
visitDuration: number;
|
|
147
|
+
events: number;
|
|
148
|
+
}
|
|
149
|
+
interface PlausibleClient {
|
|
150
|
+
getTimeseries: (siteId: string, period?: string) => Promise<PlausibleTimeseriesPoint[]>;
|
|
151
|
+
getBreakdown: (siteId: string, property: string, period?: string) => Promise<PlausibleBreakdownEntry[]>;
|
|
152
|
+
getAggregate: (siteId: string, period?: string) => Promise<PlausibleAggregateResult>;
|
|
153
|
+
}
|
|
154
|
+
interface FathomConfig {
|
|
155
|
+
siteId: string;
|
|
156
|
+
}
|
|
157
|
+
interface FathomSite {
|
|
158
|
+
id: string;
|
|
159
|
+
name: string;
|
|
160
|
+
sharing: string;
|
|
161
|
+
}
|
|
162
|
+
interface FathomPageview {
|
|
163
|
+
pathname: string;
|
|
164
|
+
pageviews: number;
|
|
165
|
+
visitors: number;
|
|
166
|
+
avgDuration: number;
|
|
167
|
+
bounceRate: number;
|
|
168
|
+
}
|
|
169
|
+
interface FathomReferrer {
|
|
170
|
+
source: string;
|
|
171
|
+
visitors: number;
|
|
172
|
+
pageviews: number;
|
|
173
|
+
}
|
|
174
|
+
interface FathomClient {
|
|
175
|
+
getSites: () => Promise<FathomSite[]>;
|
|
176
|
+
getPageviews: (siteId: string, period?: string) => Promise<FathomPageview[]>;
|
|
177
|
+
getReferrers: (siteId: string, period?: string) => Promise<FathomReferrer[]>;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export type { ConsentState as C, FathomConfig as F, GA4Config as G, PostHogConfig as P, ScriptConfig as S, ConsentManager as a, ClarityConfig as b, PlausibleConfig as c, GA4Client as d, ClarityClient as e, PostHogClient as f, PlausibleClient as g, FathomClient as h, ClarityHeatmapData as i, ClarityInsight as j, ClarityProject as k, ConsentCategory as l, ConsentChangeCallback as m, FathomPageview as n, FathomReferrer as o, FathomSite as p, GA4Metadata as q, GA4ReportRequest as r, GA4ReportResponse as s, GA4ReportRow as t, PlausibleAggregateResult as u, PlausibleBreakdownEntry as v, PlausibleTimeseriesPoint as w, PostHogEvent as x, PostHogFunnelStep as y, PostHogTrendResult as z };
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@power-seo/tracking",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Analytics platform integration with script builders, consent management, and React components",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"require": "./dist/index.cjs",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./react": {
|
|
14
|
+
"import": "./dist/react.js",
|
|
15
|
+
"require": "./dist/react.cjs",
|
|
16
|
+
"types": "./dist/react.d.ts"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"main": "./dist/index.cjs",
|
|
20
|
+
"module": "./dist/index.js",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup",
|
|
27
|
+
"dev": "tsup --watch",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"lint": "eslint src/",
|
|
32
|
+
"lint:fix": "eslint src/ --fix",
|
|
33
|
+
"clean": "rimraf dist"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependenciesMeta": {
|
|
39
|
+
"react": {
|
|
40
|
+
"optional": true
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@testing-library/react": "^16.0.0",
|
|
45
|
+
"@types/react": "^19.0.0",
|
|
46
|
+
"jsdom": "^25.0.0",
|
|
47
|
+
"react": "^19.0.0",
|
|
48
|
+
"react-dom": "^19.0.0",
|
|
49
|
+
"rimraf": "^6.0.0",
|
|
50
|
+
"tsup": "^8.3.0",
|
|
51
|
+
"typescript": "^5.7.0",
|
|
52
|
+
"vitest": "^2.1.0"
|
|
53
|
+
},
|
|
54
|
+
"keywords": [
|
|
55
|
+
"seo",
|
|
56
|
+
"analytics",
|
|
57
|
+
"ga4",
|
|
58
|
+
"clarity",
|
|
59
|
+
"posthog",
|
|
60
|
+
"plausible",
|
|
61
|
+
"fathom",
|
|
62
|
+
"tracking",
|
|
63
|
+
"consent",
|
|
64
|
+
"react",
|
|
65
|
+
"typescript"
|
|
66
|
+
],
|
|
67
|
+
"sideEffects": false,
|
|
68
|
+
"author": "CyberCraft Bangladesh <info@ccbd.dev>",
|
|
69
|
+
"repository": {
|
|
70
|
+
"type": "git",
|
|
71
|
+
"url": "git+https://github.com/cybercraftbd/power-seo.git",
|
|
72
|
+
"directory": "packages/tracking"
|
|
73
|
+
},
|
|
74
|
+
"publishConfig": {
|
|
75
|
+
"access": "public"
|
|
76
|
+
}
|
|
77
|
+
}
|