@webority/analytics 0.36.1 → 0.38.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/dist/check-events.js +14 -14
- package/dist/chunk-LGUY6CCC.js +1 -0
- package/dist/chunk-UMKCGH25.js +1 -0
- package/dist/errors.js +1 -1
- package/dist/generate-events.js +12 -12
- package/dist/index.js +1 -1
- package/dist/node.js +1 -1
- package/dist/react-native.js +1 -1
- package/dist/site.js +1 -1
- package/dist/types/after-interaction.d.ts +6 -0
- package/dist/types/analytics.d.ts +49 -0
- package/dist/types/attribution.d.ts +34 -0
- package/dist/types/catalogue/check-events.d.ts +2 -0
- package/dist/types/catalogue/check.d.ts +32 -0
- package/dist/types/catalogue/generate-events.d.ts +2 -0
- package/dist/types/catalogue/generate.d.ts +28 -0
- package/dist/types/catalogue/plan.d.ts +97 -0
- package/dist/types/catalogue/scan.d.ts +42 -0
- package/dist/types/channels.d.ts +24 -0
- package/dist/types/consent-regions.d.ts +2 -0
- package/dist/types/consent.d.ts +83 -0
- package/dist/types/errors.d.ts +35 -0
- package/dist/types/event-registry.d.ts +19 -0
- package/dist/types/feature-flags.d.ts +26 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/node/errors.d.ts +38 -0
- package/dist/types/node/index.d.ts +1 -0
- package/dist/types/posthog-bridge.d.ts +22 -0
- package/dist/types/react-native/index.d.ts +90 -0
- package/dist/types/react-native/native-modules.d.ts +41 -0
- package/dist/types/site-events.d.ts +16 -0
- package/dist/types/site-posthog-snippet.d.ts +27 -0
- package/dist/types/site-posthog.d.ts +62 -0
- package/dist/types/site-web-vitals-script.d.ts +13 -0
- package/dist/types/site-web-vitals.d.ts +4 -0
- package/dist/types/site.d.ts +8 -0
- package/dist/types/state.d.ts +43 -0
- package/dist/types/tags.d.ts +35 -0
- package/dist/types/tours.d.ts +8 -0
- package/dist/types/track-helpers.d.ts +8 -0
- package/dist/types/url-scrub.d.ts +14 -0
- package/dist/types/vocabulary.d.ts +76 -0
- package/dist/types/web-vitals-global.d.ts +1 -0
- package/dist/types/web-vitals.d.ts +71 -0
- package/dist/{web-vitals-RMISAXOY.js → web-vitals-DND62YT4.js} +1 -1
- package/dist/webority-analytics-site.global.js +1 -1
- package/dist/webority-analytics-web-vitals.global.js +1 -1
- package/package.json +31 -12
- package/dist/chunk-BXYJOYLR.js +0 -1
- package/dist/chunk-TPTUIQE4.js +0 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { MergedPlan } from "./plan.ts";
|
|
2
|
+
export type SourceProblem = {
|
|
3
|
+
file: string | null;
|
|
4
|
+
line: number | null;
|
|
5
|
+
message: string;
|
|
6
|
+
};
|
|
7
|
+
export type CheckSummary = {
|
|
8
|
+
constants: number;
|
|
9
|
+
callSites: number;
|
|
10
|
+
files: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function fleetConstantsOf(plan: MergedPlan): Map<string, string>;
|
|
13
|
+
/**
|
|
14
|
+
* Checks a product's source against its merged plan. For each source in the plan:
|
|
15
|
+
* - every event constant in its constant files must be an event in the plan;
|
|
16
|
+
* - every use of those constants in the scanned folders must name a known constant, the plan must
|
|
17
|
+
* list the source's sender for that event, and each property written inline must be declared on
|
|
18
|
+
* the event or as a common property;
|
|
19
|
+
* - every event name written in a call of the source's `calls` (and, in JavaScript, of
|
|
20
|
+
* trackSiteEvent) must be in the plan, held to the same sender and property rules.
|
|
21
|
+
* Returns { problems: [{ file, line, message }], summary }.
|
|
22
|
+
*/
|
|
23
|
+
export declare function checkSources(plan: MergedPlan, root: string): {
|
|
24
|
+
problems: SourceProblem[];
|
|
25
|
+
summary: CheckSummary;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* The folder a plan's source paths are relative to: the repo root when the plan sits in `.webority/`,
|
|
29
|
+
* otherwise the plan's own folder.
|
|
30
|
+
*/
|
|
31
|
+
export declare function defaultRootOf(planFile: string): string;
|
|
32
|
+
export declare function toPascalCase(name: string): string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CatalogueEvent, MergedPlan } from "./plan.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The events a generated file carries, in plan order: fleet events first, then the product's own.
|
|
4
|
+
* sender limits them to one sender's events; productOnly drops the ones the base plan defines.
|
|
5
|
+
*/
|
|
6
|
+
export declare function selectEvents(plan: MergedPlan, { sender, productOnly }?: {
|
|
7
|
+
sender?: string | null;
|
|
8
|
+
productOnly?: boolean;
|
|
9
|
+
}): CatalogueEvent[];
|
|
10
|
+
/**
|
|
11
|
+
* A JavaScript module exporting one frozen object of event names. keys "constant" gives
|
|
12
|
+
* SIGNUP_STARTED (the package's own `events` style), "pascal" gives SignupStarted.
|
|
13
|
+
*/
|
|
14
|
+
export declare function renderJavaScript(events: CatalogueEvent[], { exportName, keys, planLabel, }?: {
|
|
15
|
+
exportName?: string;
|
|
16
|
+
keys?: "constant" | "pascal";
|
|
17
|
+
planLabel?: string;
|
|
18
|
+
}): string;
|
|
19
|
+
/**
|
|
20
|
+
* A C# file holding one static class of event-name constants, file-scoped namespace, marked
|
|
21
|
+
* auto-generated so analyzers leave it alone.
|
|
22
|
+
*/
|
|
23
|
+
export declare function renderCSharp(events: CatalogueEvent[], { namespace, className, accessibility, planLabel, }: {
|
|
24
|
+
namespace: string;
|
|
25
|
+
className: string;
|
|
26
|
+
accessibility?: "public" | "internal";
|
|
27
|
+
planLabel?: string;
|
|
28
|
+
}): string;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export declare const FLEET_PLAN_ID = "@webority/analytics/fleet";
|
|
2
|
+
export declare const FUNNEL_STAGES: readonly ["acquisition", "activation", "engagement", "retention", "revenue", "referral", "support", "quality"];
|
|
3
|
+
export type FunnelStage = (typeof FUNNEL_STAGES)[number];
|
|
4
|
+
export declare const PERSONAL_DATA_CLASSES: readonly ["none", "pseudonymous", "personal"];
|
|
5
|
+
export type PersonalDataClass = (typeof PERSONAL_DATA_CLASSES)[number];
|
|
6
|
+
export declare const PROPERTY_TYPES: readonly ["string", "integer", "number", "boolean", "array", "object"];
|
|
7
|
+
export type PropertyType = (typeof PROPERTY_TYPES)[number];
|
|
8
|
+
export declare const PROPERTY_NAME_PATTERN: RegExp;
|
|
9
|
+
declare const LANGUAGES: readonly ["csharp", "javascript"];
|
|
10
|
+
export type SourceLanguage = (typeof LANGUAGES)[number];
|
|
11
|
+
export type PropertyDefinition = {
|
|
12
|
+
type: PropertyType;
|
|
13
|
+
description?: string;
|
|
14
|
+
values?: unknown[];
|
|
15
|
+
nullable?: boolean;
|
|
16
|
+
personalData?: PersonalDataClass;
|
|
17
|
+
};
|
|
18
|
+
export type EventDefinition = {
|
|
19
|
+
description?: string;
|
|
20
|
+
stage?: FunnelStage;
|
|
21
|
+
owner?: string;
|
|
22
|
+
personalData?: PersonalDataClass;
|
|
23
|
+
senders?: string[];
|
|
24
|
+
properties?: Record<string, PropertyDefinition>;
|
|
25
|
+
};
|
|
26
|
+
export type SourceDefinition = {
|
|
27
|
+
sender: string;
|
|
28
|
+
language: SourceLanguage;
|
|
29
|
+
constants?: string[];
|
|
30
|
+
references?: string[];
|
|
31
|
+
calls?: string[];
|
|
32
|
+
ignoreConstants?: string[];
|
|
33
|
+
scan?: string[];
|
|
34
|
+
exclude?: string[];
|
|
35
|
+
};
|
|
36
|
+
export type TrackingPlan = {
|
|
37
|
+
$schema?: string;
|
|
38
|
+
product: string;
|
|
39
|
+
extends?: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
commonProperties?: Record<string, PropertyDefinition>;
|
|
42
|
+
events: Record<string, EventDefinition>;
|
|
43
|
+
sources?: SourceDefinition[];
|
|
44
|
+
};
|
|
45
|
+
export type CatalogueEvent = {
|
|
46
|
+
name: string;
|
|
47
|
+
description: string | undefined;
|
|
48
|
+
stage: FunnelStage | undefined;
|
|
49
|
+
owner: string | undefined;
|
|
50
|
+
personalData: PersonalDataClass | undefined;
|
|
51
|
+
senders: string[];
|
|
52
|
+
properties: Map<string, PropertyDefinition>;
|
|
53
|
+
origin: string;
|
|
54
|
+
};
|
|
55
|
+
export type CommonProperty = PropertyDefinition & {
|
|
56
|
+
origin: string;
|
|
57
|
+
};
|
|
58
|
+
export type MergedPlan = {
|
|
59
|
+
product: string;
|
|
60
|
+
events: Map<string, CatalogueEvent>;
|
|
61
|
+
commonProperties: Map<string, CommonProperty>;
|
|
62
|
+
sources: SourceDefinition[];
|
|
63
|
+
file: string;
|
|
64
|
+
};
|
|
65
|
+
export type PlanLoad = {
|
|
66
|
+
plan: MergedPlan | null;
|
|
67
|
+
problems: string[];
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Reads a tracking plan and everything it extends, merged into one catalogue. Never throws on a bad
|
|
71
|
+
* plan: every problem is returned, so a check can list them all at once.
|
|
72
|
+
* Returns { plan, problems } where plan is { product, events: Map, commonProperties: Map, sources, file }.
|
|
73
|
+
*/
|
|
74
|
+
export declare function loadPlan(file: string): PlanLoad;
|
|
75
|
+
export declare function loadFleetPlan(): PlanLoad;
|
|
76
|
+
/**
|
|
77
|
+
* Merges a plan's own declarations over its base. A product may list a base event again only to add
|
|
78
|
+
* properties or senders; anything else on it, or a property redeclared with another type, is a problem.
|
|
79
|
+
*/
|
|
80
|
+
export declare function mergePlan(base: MergedPlan | null, raw: TrackingPlan, label?: string): {
|
|
81
|
+
plan: MergedPlan;
|
|
82
|
+
problems: string[];
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* The structural rules of tracking-plan.schema.json, checked without a schema library so the check
|
|
86
|
+
* has no runtime dependency. The schema is what an editor validates against; this is what the build
|
|
87
|
+
* enforces, and the catalogue test keeps their enums the same.
|
|
88
|
+
*/
|
|
89
|
+
export declare function validatePlanShape(raw: unknown, label?: string): string[];
|
|
90
|
+
/**
|
|
91
|
+
* Checks one event as it would be sent: a name the catalogue does not hold, a property declared
|
|
92
|
+
* neither on the event nor as a common property, or a value of the wrong type. PostHog's own `$`
|
|
93
|
+
* events and properties are not the product's vocabulary and are skipped.
|
|
94
|
+
* Returns a list of problem strings, empty when the event is valid.
|
|
95
|
+
*/
|
|
96
|
+
export declare function validateEvent(plan: MergedPlan, name: unknown, properties?: unknown): string[];
|
|
97
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { SourceLanguage } from "./plan.ts";
|
|
2
|
+
export type ConstantEntry = {
|
|
3
|
+
name: string;
|
|
4
|
+
value: string | null;
|
|
5
|
+
line: number;
|
|
6
|
+
};
|
|
7
|
+
export type EventReference = {
|
|
8
|
+
constant: string;
|
|
9
|
+
line: number;
|
|
10
|
+
properties: string[] | null;
|
|
11
|
+
};
|
|
12
|
+
export type EventCall = {
|
|
13
|
+
call: string;
|
|
14
|
+
name: string;
|
|
15
|
+
line: number;
|
|
16
|
+
properties: string[] | null;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Event constants declared in a C# file: `const string Name = "value";`, or `= AnalyticsEvents.X;`
|
|
20
|
+
* resolved through fleetConstants (PascalCase name to event name). Nested classes are flattened to
|
|
21
|
+
* the constant's own name. Returns [{ name, value, line }]; value is null for a reference that
|
|
22
|
+
* cannot be resolved.
|
|
23
|
+
*/
|
|
24
|
+
export declare function readCSharpConstants(text: string, fleetConstants?: ReadonlyMap<string, string>): ConstantEntry[];
|
|
25
|
+
/**
|
|
26
|
+
* Event constants declared in a JavaScript file as string values of object literals,
|
|
27
|
+
* `Key: "value"` or `KEY: 'value'`. Returns [{ name, value, line }].
|
|
28
|
+
*/
|
|
29
|
+
export declare function readJavaScriptConstants(text: string): ConstantEntry[];
|
|
30
|
+
/**
|
|
31
|
+
* Every use of `<reference>.<Constant>` (or `<reference>.<Nested>.<Constant>`) in a source file, with
|
|
32
|
+
* the property names written inline beside it. Returns [{ constant, line, properties }], where
|
|
33
|
+
* properties is an array of names, or null when no inline properties were found.
|
|
34
|
+
*/
|
|
35
|
+
export declare function findEventReferences(text: string, references: readonly string[], language: SourceLanguage): EventReference[];
|
|
36
|
+
/**
|
|
37
|
+
* Every call of one of the named functions (`trackSiteEvent("x", ...)`, `window.lumexTrack("x", ...)`)
|
|
38
|
+
* whose first argument writes its event name, with the property names written inline beside it.
|
|
39
|
+
* Returns [{ call, name, line, properties }], one entry per name, so both arms of a ternary count.
|
|
40
|
+
*/
|
|
41
|
+
export declare function findEventCalls(text: string, calls: readonly string[], language: SourceLanguage): EventCall[];
|
|
42
|
+
export declare function maskComments(text: string, language: SourceLanguage): string;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AttributionTouch } from "./attribution.ts";
|
|
2
|
+
declare const AI_ASSISTANTS: readonly [readonly ["chatgpt", readonly ["chatgpt.com", "chat.openai.com"]], readonly ["perplexity", readonly ["perplexity.ai"]], readonly ["gemini", readonly ["gemini.google.com"]], readonly ["copilot", readonly ["copilot.microsoft.com"]], readonly ["claude", readonly ["claude.ai"]], readonly ["you", readonly ["you.com"]], readonly ["phind", readonly ["phind.com"]], readonly ["deepseek", readonly ["deepseek.com"]], readonly ["grok", readonly ["grok.com"]], readonly ["meta_ai", readonly ["meta.ai"]], readonly ["poe", readonly ["poe.com"]]];
|
|
3
|
+
type AiAssistant = (typeof AI_ASSISTANTS)[number][0];
|
|
4
|
+
export declare const channels: Readonly<{
|
|
5
|
+
readonly DIRECT: "direct";
|
|
6
|
+
readonly GOOGLE: "google";
|
|
7
|
+
readonly META: "meta";
|
|
8
|
+
readonly LINKEDIN: "linkedin";
|
|
9
|
+
readonly MICROSOFT: "microsoft";
|
|
10
|
+
readonly OTHER: "other";
|
|
11
|
+
readonly AI_ASSISTANT: "ai_assistant";
|
|
12
|
+
readonly ORGANIC_SEARCH: "organic_search";
|
|
13
|
+
readonly ORGANIC_SOCIAL: "organic_social";
|
|
14
|
+
readonly REFERRAL: "referral";
|
|
15
|
+
}>;
|
|
16
|
+
type Channel = (typeof channels)[keyof typeof channels];
|
|
17
|
+
/**
|
|
18
|
+
* The channel of a touch, as captureAttribution stores it. utm_source wins, then click ids; an
|
|
19
|
+
* untagged visit is classified by its referrer's host.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveChannel(touch: Partial<AttributionTouch> | null | undefined): Channel;
|
|
22
|
+
/** The AI assistant ("chatgpt", "perplexity", "gemini", "copilot", "claude"...) behind a touch, or "". */
|
|
23
|
+
export declare function resolveAiSource(touch: Partial<AttributionTouch> | null | undefined): AiAssistant | "";
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const OPT_IN_COUNTRIES: readonly ["AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT", "RO", "SK", "SI", "ES", "SE", "IS", "LI", "NO", "GB", "CH"];
|
|
2
|
+
export declare function requiresOptIn(countryCode: string | null | undefined): boolean;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export declare const CONSENT_COOKIE_NAME = "webority_cookie_consent";
|
|
2
|
+
export declare const CONSENT_CHANGE_EVENT = "webority-consent-change";
|
|
3
|
+
declare global {
|
|
4
|
+
interface Window {
|
|
5
|
+
dataLayer?: unknown[];
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
/** The categories a visitor chooses between. Essential cookies are always on, so they are not a choice. */
|
|
9
|
+
export type ConsentCategory = "analytics" | "functional" | "marketing";
|
|
10
|
+
/**
|
|
11
|
+
* The saved choice, shaped as the webority_cookie_consent cookie holds it. timestamp is an ISO
|
|
12
|
+
* string when this package wrote the cookie. A cookie edited by hand can hold any JSON value there,
|
|
13
|
+
* so it stays unknown and is only read after a type check.
|
|
14
|
+
*/
|
|
15
|
+
export type ConsentState = Record<ConsentCategory, boolean> & {
|
|
16
|
+
essential: true;
|
|
17
|
+
timestamp: unknown;
|
|
18
|
+
};
|
|
19
|
+
type SharedConsentOptions = {
|
|
20
|
+
cookieDomain?: string;
|
|
21
|
+
cookieDays?: number;
|
|
22
|
+
adStorage?: boolean;
|
|
23
|
+
regionCookie?: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* The initConsent options. requiresOptIn comes from the host's country lookup and is required, except
|
|
27
|
+
* under strictOptIn, which asks every region and so may leave it out. requiresOptIn: false beside
|
|
28
|
+
* strictOptIn throws at run time, and the type rules it out too.
|
|
29
|
+
*/
|
|
30
|
+
export type ConsentOptions = SharedConsentOptions & ({
|
|
31
|
+
requiresOptIn: boolean;
|
|
32
|
+
strictOptIn?: false | undefined;
|
|
33
|
+
} | {
|
|
34
|
+
requiresOptIn?: true | undefined;
|
|
35
|
+
strictOptIn: true;
|
|
36
|
+
});
|
|
37
|
+
type Region = "eea" | "other";
|
|
38
|
+
type ConsentView = Omit<ConsentState, "timestamp"> & {
|
|
39
|
+
decided: boolean;
|
|
40
|
+
};
|
|
41
|
+
type ConsentListener = (consent: ConsentView) => void;
|
|
42
|
+
/**
|
|
43
|
+
* Sets Google Consent Mode's defaults and applies the visitor's saved choice. Call once, first,
|
|
44
|
+
* before initAnalytics, loadTags or captureAttribution. requiresOptIn comes from the host, which
|
|
45
|
+
* knows the visitor's country (requiresOptIn(countryCode)); guessing it in the browser misplaces
|
|
46
|
+
* VPN users. cookieDomain (".capnix.ai") shares one choice between the website and every portal
|
|
47
|
+
* subdomain; without it the choice stays on the current host.
|
|
48
|
+
*
|
|
49
|
+
* strictOptIn asks every visitor in every region: Consent Mode is denied everywhere until they
|
|
50
|
+
* choose, loadTags holds Tag Manager and Ahrefs until consent, and requiresOptIn may be left out.
|
|
51
|
+
* adStorage says whether marketing consent also grants Google's ad_* signals: true by default,
|
|
52
|
+
* false under strictOptIn. cookieDays is the saved choice's lifetime, 365 by default.
|
|
53
|
+
*
|
|
54
|
+
* regionCookie names a cookie the host sets to "eea" or "other" (see setConsentRegion), read
|
|
55
|
+
* once, synchronously, here. With no saved choice, "other" lifts the opt-in default: analytics and
|
|
56
|
+
* functional start on, marketing stays off until chosen, and Google's ad signals follow adStorage.
|
|
57
|
+
* "eea", a missing cookie or any other value keeps the opt-in default. strictOptIn ignores it, and
|
|
58
|
+
* a saved choice always wins.
|
|
59
|
+
*/
|
|
60
|
+
export declare function initConsent(options: ConsentOptions): void;
|
|
61
|
+
/**
|
|
62
|
+
* Applies the visitor's region when the host learns it after initConsent (a country check that
|
|
63
|
+
* answered later than the page). "other" lifts the opt-in default and "eea" restores it, with the
|
|
64
|
+
* same rule initConsent's regionCookie applies. onConsentChange listeners fire when the effective
|
|
65
|
+
* consent changes; a saved choice is untouched and nothing fires.
|
|
66
|
+
*/
|
|
67
|
+
export declare function setConsentRegion(region: Region): void;
|
|
68
|
+
export declare function isConsentInitialized(): boolean;
|
|
69
|
+
export declare function isStrictOptIn(): boolean;
|
|
70
|
+
export declare function isAdStorageEnabled(): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* The visitor's current consent. Before they choose (decided: false) every optional category
|
|
73
|
+
* follows the region default: denied where opt-in is required, granted everywhere else. A region
|
|
74
|
+
* of "other" (regionCookie, setConsentRegion) grants analytics and functional where opt-in would
|
|
75
|
+
* otherwise be required; marketing stays off until the visitor chooses it.
|
|
76
|
+
*/
|
|
77
|
+
export declare function getConsent(): ConsentView;
|
|
78
|
+
/** Records the visitor's choice, tells Google, and notifies every listener. */
|
|
79
|
+
export declare function saveConsent(preferences?: Partial<Record<ConsentCategory, boolean>>): void;
|
|
80
|
+
/** Calls listener with the new consent after every saveConsent. Returns an unsubscribe function. */
|
|
81
|
+
export declare function onConsentChange(listener: ConsentListener): () => boolean;
|
|
82
|
+
export declare function resetConsentForTests(): void;
|
|
83
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { PostHog } from "posthog-js";
|
|
2
|
+
type ErrorState = {
|
|
3
|
+
started: boolean;
|
|
4
|
+
posthog: PostHog | null;
|
|
5
|
+
pending: [unknown, Record<string, unknown> | undefined][];
|
|
6
|
+
loadPosthog: () => Promise<{
|
|
7
|
+
default: PostHog;
|
|
8
|
+
}>;
|
|
9
|
+
};
|
|
10
|
+
/** PostHog options for error tracking only: exceptions are sent, nothing else is. Pure, so the test can lock the mapping. */
|
|
11
|
+
export declare function buildErrorTrackingInitOptions({ host }: {
|
|
12
|
+
host: string;
|
|
13
|
+
}): Parameters<PostHog["init"]>[1];
|
|
14
|
+
/**
|
|
15
|
+
* Starts exception tracking in the browser, once per page. No initConsent is needed: nothing is
|
|
16
|
+
* stored on the device (memory persistence), no person is profiled and only exceptions are sent.
|
|
17
|
+
* Call it in the browser, once per page; in Next.js that is inside a useEffect in _app.
|
|
18
|
+
* Nothing starts when disabled, in Local, or when a host, client key, product or environment is missing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function initErrorTracking({ host, clientKey, product, surface, environment, release, enabled, }?: {
|
|
21
|
+
host?: string;
|
|
22
|
+
clientKey?: string;
|
|
23
|
+
product?: string;
|
|
24
|
+
surface?: string | undefined;
|
|
25
|
+
environment?: string;
|
|
26
|
+
release?: string | undefined;
|
|
27
|
+
enabled?: boolean;
|
|
28
|
+
}): void;
|
|
29
|
+
/**
|
|
30
|
+
* Reports an exception the page caught itself, such as one stopped by a React error boundary,
|
|
31
|
+
* which never reaches the global handlers. Does nothing unless initErrorTracking has started.
|
|
32
|
+
*/
|
|
33
|
+
export declare function captureBrowserException(error: unknown, properties?: Record<string, unknown>): void;
|
|
34
|
+
export declare function resetErrorTrackingForTests(loadPosthog?: ErrorState["loadPosthog"]): void;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { FleetEventName } from "./vocabulary.ts";
|
|
2
|
+
/** A value PostHog can store and a JSON event body can carry. */
|
|
3
|
+
export type EventPropertyValue = string | number | boolean | null | EventPropertyValue[] | {
|
|
4
|
+
[key: string]: EventPropertyValue;
|
|
5
|
+
};
|
|
6
|
+
/** The properties an event, identify or group call carries. */
|
|
7
|
+
export type EventProperties = {
|
|
8
|
+
[key: string]: EventPropertyValue;
|
|
9
|
+
};
|
|
10
|
+
export type EventName = FleetEventName | (string & Record<never, never>);
|
|
11
|
+
/**
|
|
12
|
+
* The event names an entry may send: the fleet vocabulary plus every name the product registers.
|
|
13
|
+
* Each entry owns one, kept outside its session state, because an event name belongs to the
|
|
14
|
+
* product's vocabulary rather than to one analytics session.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createEventRegistry(): {
|
|
17
|
+
register(names: Iterable<string>): void;
|
|
18
|
+
assertRegistered(name: EventName): void;
|
|
19
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PostHog } from "posthog-js";
|
|
2
|
+
/**
|
|
3
|
+
* Whether a PostHog feature flag is on for this person. False whenever the answer cannot be
|
|
4
|
+
* trusted: flags not turned on in initAnalytics, analytics off or Local, no analytics consent
|
|
5
|
+
* (a revoke included), or PostHog still loading. A PostHog failure also reads as false, the default
|
|
6
|
+
* for the current render, but is never silent: it is sent to the logger passed to initAnalytics and
|
|
7
|
+
* rethrown on its own turn so the page's error reporting sees it. PostHog's own call records the
|
|
8
|
+
* exposure as $feature_flag_called. Never throws into the caller's own turn.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isFeatureEnabled(key: string): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* The flag's value: the variant key for a multivariate flag (an experiment), true or false for a
|
|
13
|
+
* plain one. Null under the same conditions as isFeatureEnabled returns false, and for an unknown
|
|
14
|
+
* flag. A PostHog failure reads as null for the current render, is sent to the logger and rethrown
|
|
15
|
+
* on its own turn, as isFeatureEnabled does; records the exposure like isFeatureEnabled.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getFeatureFlag(key: string): string | boolean | null;
|
|
18
|
+
/**
|
|
19
|
+
* Calls listener whenever flags become readable: when PostHog loads or reloads them (after
|
|
20
|
+
* consent, identify, group). When they cannot load now (flags off, analytics off, no consent) it
|
|
21
|
+
* is called once on the next turn, so a screen waiting on it renders its default instead of
|
|
22
|
+
* waiting forever. Read the values inside it with isFeatureEnabled or getFeatureFlag. Returns an
|
|
23
|
+
* unsubscribe function that works at any time, before initAnalytics included.
|
|
24
|
+
*/
|
|
25
|
+
export declare function onFeatureFlags(listener: () => void): () => boolean;
|
|
26
|
+
export declare function followFeatureFlags(posthog: PostHog): void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { group, identify, initAnalytics, resetIdentity, trackEvent, WORKSPACE_GROUP_TYPE } from "./analytics.ts";
|
|
2
|
+
export { getFeatureFlag, isFeatureEnabled, onFeatureFlags } from "./feature-flags.ts";
|
|
3
|
+
export { CONSENT_CHANGE_EVENT, CONSENT_COOKIE_NAME, captureAttribution, channels, events, getAttribution, getConsent, initConsent, loadTags, onConsentChange, registerEvents, requiresOptIn, resolveAiSource, resolveChannel, saveConsent, setConsentRegion, trackSiteEvent, } from "./site.ts";
|
|
4
|
+
export { trackTours } from "./tours.ts";
|
|
5
|
+
export { track } from "./track-helpers.ts";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { PostHog } from "posthog-node";
|
|
2
|
+
type NodeErrorState = {
|
|
3
|
+
client: PostHog | null;
|
|
4
|
+
base: Record<string, unknown>;
|
|
5
|
+
createClient: (key: string, options: NonNullable<ConstructorParameters<typeof PostHog>[1]>) => PostHog;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Starts exception tracking on the server, once per process. Nothing starts when disabled, in Local,
|
|
9
|
+
* when already started, or when a host, client key, product or environment is missing.
|
|
10
|
+
* captureUncaught also reports uncaught exceptions and unhandled rejections.
|
|
11
|
+
*/
|
|
12
|
+
export declare function initServerErrorTracking({ host, clientKey, product, surface, environment, release, enabled, captureUncaught, }?: {
|
|
13
|
+
host?: string;
|
|
14
|
+
clientKey?: string;
|
|
15
|
+
product?: string;
|
|
16
|
+
surface?: string | undefined;
|
|
17
|
+
environment?: string;
|
|
18
|
+
release?: string | undefined;
|
|
19
|
+
enabled?: boolean;
|
|
20
|
+
captureUncaught?: boolean;
|
|
21
|
+
}): void;
|
|
22
|
+
/** Sends an exception with the request it came from. Does nothing until initServerErrorTracking has run. */
|
|
23
|
+
export declare function captureServerException(error: unknown, { distinctId, path, method, statusCode, properties, }?: {
|
|
24
|
+
distinctId?: string;
|
|
25
|
+
path?: string;
|
|
26
|
+
method?: string;
|
|
27
|
+
statusCode?: unknown;
|
|
28
|
+
properties?: Record<string, unknown>;
|
|
29
|
+
}): void;
|
|
30
|
+
/** Express error middleware: records the error, then passes it on so Express answers as it would without tracking. */
|
|
31
|
+
export declare function expressErrorHandler(): (err: unknown, req: {
|
|
32
|
+
originalUrl: string;
|
|
33
|
+
method: string;
|
|
34
|
+
}, _res: unknown, next: (err: unknown) => void) => void;
|
|
35
|
+
/** Sends what is queued and stops the client, within timeoutMs. Call it on shutdown, before the process exits. */
|
|
36
|
+
export declare function flushServerErrorTracking(timeoutMs?: number): Promise<void>;
|
|
37
|
+
export declare function resetServerErrorTrackingForTests(createClient?: NodeErrorState["createClient"]): void;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { captureServerException, expressErrorHandler, flushServerErrorTracking, initServerErrorTracking, resetServerErrorTrackingForTests, } from "./errors.ts";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PostHog, PostHogConfig } from "posthog-js";
|
|
2
|
+
import { type ResolvedAnalyticsConfig } from "./state.ts";
|
|
3
|
+
export type PosthogInitOptions = Partial<PostHogConfig> & Record<string, unknown>;
|
|
4
|
+
/** What buildInitOptions reads from a config: initAnalytics passes its resolved config, initSiteAnalytics only these. */
|
|
5
|
+
export type PosthogInitConfig = Pick<ResolvedAnalyticsConfig, "host" | "heatmaps" | "captureExceptions"> & {
|
|
6
|
+
sessionRecording?: ResolvedAnalyticsConfig["sessionRecording"] | undefined;
|
|
7
|
+
featureFlags?: boolean | undefined;
|
|
8
|
+
};
|
|
9
|
+
export declare function ensurePosthogInitialized(): Promise<PostHog>;
|
|
10
|
+
/**
|
|
11
|
+
* Copies init options and, when consent is absent, sets the flag that keeps init itself
|
|
12
|
+
* from capturing. Pure so the smoke test can lock the consent decision without a browser.
|
|
13
|
+
* With the product's flags on it also holds the first flags request: opting out does not stop
|
|
14
|
+
* posthog-js asking for flags, and that request names the visitor. The grant reloads them.
|
|
15
|
+
*/
|
|
16
|
+
export declare function applyConsentToInitOptions(options: PosthogInitOptions, consentGranted: boolean, featureFlags?: boolean): PosthogInitOptions;
|
|
17
|
+
/**
|
|
18
|
+
* The posthog-js init options for a config. Pure, so the smoke test can assert the mapping
|
|
19
|
+
* without a browser: replay stays off unless the product enabled it, and the masking choices
|
|
20
|
+
* ride through only when it is on.
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildInitOptions(config: PosthogInitConfig): PosthogInitOptions;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { AnalyticsLogger } from "../analytics.ts";
|
|
2
|
+
import type { EventName, EventProperties } from "../event-registry.ts";
|
|
3
|
+
import { events } from "../vocabulary.ts";
|
|
4
|
+
export { __setNativeModulesForTests } from "./native-modules.ts";
|
|
5
|
+
export { events };
|
|
6
|
+
export declare const CONSENT_STORAGE_KEY = "webority_analytics_consent";
|
|
7
|
+
declare const REGIONS: readonly ["eea", "other"];
|
|
8
|
+
type ConsentRegion = (typeof REGIONS)[number];
|
|
9
|
+
export declare const WORKSPACE_GROUP_TYPE = "workspace";
|
|
10
|
+
type KeyValueStorage = {
|
|
11
|
+
getItem(key: string): Promise<string | null>;
|
|
12
|
+
setItem(key: string, value: string): Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
type MobileInit = {
|
|
15
|
+
host?: string;
|
|
16
|
+
clientKey?: string;
|
|
17
|
+
product?: string;
|
|
18
|
+
surface?: string;
|
|
19
|
+
environment?: string;
|
|
20
|
+
enabled?: boolean;
|
|
21
|
+
logger?: AnalyticsLogger;
|
|
22
|
+
storage?: KeyValueStorage;
|
|
23
|
+
featureFlags?: boolean;
|
|
24
|
+
requiresOptIn?: boolean;
|
|
25
|
+
};
|
|
26
|
+
type MobileConsent = {
|
|
27
|
+
analytics: boolean;
|
|
28
|
+
decided: boolean;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Reads the stored choice and, when the config is complete and not Local, starts PostHog opted
|
|
32
|
+
* out. It opts in only while analytics consent holds. requiresOptIn comes from the person's
|
|
33
|
+
* country, as on the web; with no stored choice and opt-in required, nothing is sent until
|
|
34
|
+
* setConsentRegion("other") or setAnalyticsConsent(true). Resolves once PostHog is ready, never rejects.
|
|
35
|
+
*/
|
|
36
|
+
export declare function initMobileAnalytics(config?: MobileInit): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Applies the person's region when the app learns it. "other" grants analytics by default when
|
|
39
|
+
* no choice is stored; "eea" keeps opt-in. Listeners fire only when the effective consent changes.
|
|
40
|
+
*/
|
|
41
|
+
export declare function setConsentRegion(region: ConsentRegion): void;
|
|
42
|
+
/** Stores the person's choice, opts PostHog in or out, and notifies every listener. Never rejects. */
|
|
43
|
+
export declare function setAnalyticsConsent(granted: boolean): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* The current consent. Before a choice (decided: false) analytics follows the region default,
|
|
46
|
+
* except after a stored choice that could not be read: that is no consent, whatever the region.
|
|
47
|
+
*/
|
|
48
|
+
export declare function getAnalyticsConsent(): MobileConsent;
|
|
49
|
+
/** Calls listener with the new consent whenever it changes. Returns an unsubscribe function. */
|
|
50
|
+
export declare function onAnalyticsConsentChange(listener: (consent: MobileConsent) => void): () => boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Names the person by their PublicId, never an internal id or an email. Made before consent, it
|
|
53
|
+
* is kept and applied when analytics is allowed; only the last one is kept.
|
|
54
|
+
*/
|
|
55
|
+
export declare function identify(publicId: string, props?: EventProperties): void;
|
|
56
|
+
/**
|
|
57
|
+
* Ties the person's later events to a PostHog group and sets the group's properties (plan,
|
|
58
|
+
* seats): group(WORKSPACE_GROUP_TYPE, workspacePublicId, props). PublicId strings only; a number
|
|
59
|
+
* throws, because an internal id never reaches analytics. Held like identify, one per type, and
|
|
60
|
+
* forgotten by resetIdentity.
|
|
61
|
+
*/
|
|
62
|
+
export declare function group(type: string, key: string, props?: EventProperties): void;
|
|
63
|
+
/**
|
|
64
|
+
* Whether a PostHog feature flag is on for this person. False whenever the answer cannot be
|
|
65
|
+
* trusted: flags not turned on in initMobileAnalytics, analytics off or Local, no consent, or
|
|
66
|
+
* PostHog still starting. A PostHog failure also reads as false for this render: it is sent to the
|
|
67
|
+
* logger passed to initMobileAnalytics and rethrown on its own turn.
|
|
68
|
+
* PostHog's own call records the exposure as $feature_flag_called.
|
|
69
|
+
*/
|
|
70
|
+
export declare function isFeatureEnabled(key: string): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* The flag's value: the variant key for a multivariate flag (an experiment), true or false for a
|
|
73
|
+
* plain one. Null when isFeatureEnabled would return false for the same reason, and for an
|
|
74
|
+
* unknown flag. A PostHog failure reads as null for this render, is sent to the logger and rethrown
|
|
75
|
+
* on its own turn, as isFeatureEnabled does; records the exposure like isFeatureEnabled.
|
|
76
|
+
*/
|
|
77
|
+
export declare function getFeatureFlag(key: string): string | boolean | null;
|
|
78
|
+
/**
|
|
79
|
+
* Calls listener whenever flags become readable (after consent, identify, group). When they
|
|
80
|
+
* cannot load now (flags off, analytics off, no consent) it is called once on the next turn, so a
|
|
81
|
+
* screen waiting on it renders its default. Returns an unsubscribe function.
|
|
82
|
+
*/
|
|
83
|
+
export declare function onFeatureFlags(listener: () => void): () => boolean;
|
|
84
|
+
export declare function resetIdentity(): void;
|
|
85
|
+
export declare function registerEvents(names: readonly string[]): void;
|
|
86
|
+
export declare function trackEvent(name: EventName, props?: EventProperties): void;
|
|
87
|
+
/** Sends a PostHog $screen view. Screen names are not event names, so they need no registration. */
|
|
88
|
+
export declare function trackScreen(screenName: string, props?: EventProperties): void;
|
|
89
|
+
/** Puts the module back to its first-load state for the smoke test. Not part of the public API. */
|
|
90
|
+
export declare function __resetForTests(): void;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
type PostHogClient = {
|
|
2
|
+
ready?(): unknown;
|
|
3
|
+
register(props: Record<string, unknown>): unknown;
|
|
4
|
+
identify(publicId: string, props: Record<string, unknown>): unknown;
|
|
5
|
+
group(type: string, key: string, props: Record<string, unknown>): unknown;
|
|
6
|
+
capture(name: string, props: Record<string, unknown>): unknown;
|
|
7
|
+
screen(name: string, props: Record<string, unknown>): unknown;
|
|
8
|
+
optIn(): unknown;
|
|
9
|
+
optOut(): unknown;
|
|
10
|
+
reset(): unknown;
|
|
11
|
+
isFeatureEnabled(key: string): boolean | undefined;
|
|
12
|
+
getFeatureFlag(key: string): string | boolean | undefined;
|
|
13
|
+
onFeatureFlags?(listener: () => void): unknown;
|
|
14
|
+
reloadFeatureFlagsAsync?(): unknown;
|
|
15
|
+
};
|
|
16
|
+
type PostHogConstructor = new (apiKey: string, options: ReturnType<typeof buildNativeOptions>) => PostHogClient;
|
|
17
|
+
/**
|
|
18
|
+
* Replaces posthog-react-native for the smoke test, which runs under plain node.
|
|
19
|
+
* Not part of the public API. Pass null to go back to the real modules.
|
|
20
|
+
*/
|
|
21
|
+
export declare function __setNativeModulesForTests(modules: unknown): void;
|
|
22
|
+
export declare function loadPostHogClass(): Promise<PostHogConstructor | null>;
|
|
23
|
+
export declare function isMissingModule(error: unknown): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The posthog-react-native constructor options for a config. Pure, so the smoke test can lock
|
|
26
|
+
* the privacy choices without a device.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildNativeOptions(config: {
|
|
29
|
+
host: string;
|
|
30
|
+
featureFlags: boolean;
|
|
31
|
+
}): {
|
|
32
|
+
host: string;
|
|
33
|
+
defaultOptIn: boolean;
|
|
34
|
+
personProfiles: string;
|
|
35
|
+
captureAppLifecycleEvents: boolean;
|
|
36
|
+
enableSessionReplay: boolean;
|
|
37
|
+
preloadFeatureFlags: boolean;
|
|
38
|
+
disableRemoteFeatureFlags: boolean;
|
|
39
|
+
disableSurveys: boolean;
|
|
40
|
+
};
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EventName, EventProperties } from "./event-registry.ts";
|
|
2
|
+
declare global {
|
|
3
|
+
interface Window {
|
|
4
|
+
dataLayer?: unknown[];
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Pushes a catalogue event (lead_submitted, whatsapp_click, calculator_use, phone_click...) to
|
|
9
|
+
* dataLayer for a Tag Manager trigger, carrying the visitor's first and last acquisition channel
|
|
10
|
+
* and ai_source. Nothing is pushed until the visitor has granted analytics consent; a name that is
|
|
11
|
+
* neither in the catalogue nor passed to registerEvents throws. When initSiteAnalytics has run, the
|
|
12
|
+
* event goes to PostHog too, held until PostHog starts, cookieless and anonymous without consent,
|
|
13
|
+
* as on the portal. Returns whether it was pushed to dataLayer.
|
|
14
|
+
*/
|
|
15
|
+
export declare function trackSiteEvent(name: EventName, props?: EventProperties): boolean;
|
|
16
|
+
export declare function registerEvents(names: Iterable<EventName>): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
declare const QUEUED_METHODS: readonly ["capture", "register", "opt_in_capturing", "opt_out_capturing"];
|
|
2
|
+
type QueuedMethod = (typeof QUEUED_METHODS)[number];
|
|
3
|
+
type SnippetOptions = {
|
|
4
|
+
api_host: string;
|
|
5
|
+
};
|
|
6
|
+
type SnippetMethods = {
|
|
7
|
+
[method in QueuedMethod]: (...args: unknown[]) => void;
|
|
8
|
+
};
|
|
9
|
+
type SnippetParts = SnippetMethods & {
|
|
10
|
+
_i: unknown[];
|
|
11
|
+
__SV: number;
|
|
12
|
+
people: unknown[];
|
|
13
|
+
init: (token: string, options: SnippetOptions) => void;
|
|
14
|
+
};
|
|
15
|
+
type SnippetQueue = unknown[] & SnippetParts;
|
|
16
|
+
type SnippetApi = {
|
|
17
|
+
init: (token: string, options: SnippetOptions) => void;
|
|
18
|
+
} & {
|
|
19
|
+
[method in QueuedMethod]?: (...args: unknown[]) => void;
|
|
20
|
+
};
|
|
21
|
+
declare global {
|
|
22
|
+
interface Window {
|
|
23
|
+
posthog?: SnippetQueue;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
declare const posthog: SnippetApi;
|
|
27
|
+
export default posthog;
|