@hogsend/core 0.18.0 → 0.19.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/package.json +2 -2
- package/src/providers/analytics.ts +102 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hogsend/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"drizzle-orm": "^0.45.2",
|
|
33
33
|
"iana-db-timezones": "^0.3.0",
|
|
34
34
|
"zod": "^4.4.3",
|
|
35
|
-
"@hogsend/db": "^0.
|
|
35
|
+
"@hogsend/db": "^0.19.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "latest",
|
|
@@ -1,20 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The provider-neutral ANALYTICS contract — the analytics sibling of
|
|
3
|
+
* {@link EmailProvider}. PostHog is one implementation
|
|
4
|
+
* (`@hogsend/plugin-posthog`'s `createPostHogProvider`), not the
|
|
5
|
+
* architecture: the engine speaks only this contract, so the event stream /
|
|
6
|
+
* person store can be Segment, Amplitude, Mixpanel, or the consumer's own
|
|
7
|
+
* service without touching engine code.
|
|
8
|
+
*
|
|
9
|
+
* A provider owns exactly three wires plus identity:
|
|
10
|
+
*
|
|
11
|
+
* - **person READ** — `getPersonProperties` (the identity PULL): per-user
|
|
12
|
+
* timezone resolution at journey enrollment and property conditions. On
|
|
13
|
+
* most platforms this requires a PRIVILEGED credential (e.g. PostHog's
|
|
14
|
+
* personal API key with `person:read`) because the public capture key is
|
|
15
|
+
* write-only by design.
|
|
16
|
+
* - **person WRITE** — `setPersonProperties`: trait propagation (contact →
|
|
17
|
+
* analytics person). On most platforms this rides the public capture
|
|
18
|
+
* pipeline (e.g. PostHog `$set`/`$set_once`) and needs NO extra credential.
|
|
19
|
+
* - **event capture** — `capture`: fire an event under a distinct id.
|
|
20
|
+
*
|
|
21
|
+
* Lifecycle fan-out (email/contact/journey/bucket events) does NOT flow
|
|
22
|
+
* through this contract — it rides outbound DESTINATIONS on the durable
|
|
23
|
+
* delivery spine. This contract is the request/response side: reads the
|
|
24
|
+
* engine needs inline, plus best-effort writes.
|
|
25
|
+
*/
|
|
26
|
+
|
|
1
27
|
/**
|
|
2
28
|
* The minimal READ contract for the identity PULL: fetching a person's
|
|
3
|
-
* properties by distinct id. This is the only role the engine
|
|
4
|
-
*
|
|
29
|
+
* properties by distinct id. This is the only role the engine REQUIRES of the
|
|
30
|
+
* injected analytics provider at the hot path — per-user timezone resolution
|
|
5
31
|
* at journey enrollment (`getPersonProperties` in `define-journey` /
|
|
6
|
-
* `lib/timezone.ts`).
|
|
7
|
-
*
|
|
8
|
-
* durable spine, NOT through this provider.
|
|
9
|
-
*
|
|
10
|
-
* `PostHogService` satisfies `IdentityProvider` (it declares
|
|
11
|
-
* `getPersonProperties` plus the deprecated capture/identify shims). Code that
|
|
12
|
-
* only needs the PULL can depend on this narrower alias.
|
|
32
|
+
* `lib/timezone.ts`). Code that only needs the PULL can depend on this
|
|
33
|
+
* narrower alias.
|
|
13
34
|
*/
|
|
14
35
|
export interface IdentityProvider {
|
|
15
36
|
getPersonProperties(distinctId: string): Promise<Record<string, unknown>>;
|
|
16
37
|
}
|
|
17
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Person-property write payload: `set` overwrites, `setOnce` only-if-absent,
|
|
41
|
+
* `unset` removes keys (e.g. the bucket mirror clears membership flags on
|
|
42
|
+
* leave — `unset` rather than `set: false` so both "key = true" and "key is
|
|
43
|
+
* set" cohort idioms behave correctly).
|
|
44
|
+
*/
|
|
45
|
+
export interface PersonPropertiesWrite {
|
|
46
|
+
set?: Record<string, unknown>;
|
|
47
|
+
setOnce?: Record<string, unknown>;
|
|
48
|
+
unset?: string[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** What an {@link AnalyticsProvider} can actually do, given its credentials. */
|
|
52
|
+
export interface AnalyticsCapabilities {
|
|
53
|
+
/**
|
|
54
|
+
* True when the provider is configured for person READS (e.g. PostHog has a
|
|
55
|
+
* personal API key with `person:read`). When false, `getPersonProperties`
|
|
56
|
+
* soft-fails to `{}` and the engine's fallbacks (contact properties →
|
|
57
|
+
* client default timezone) take over.
|
|
58
|
+
*/
|
|
59
|
+
personReads: boolean;
|
|
60
|
+
/** True when person WRITES are available (usually the capture pipeline). */
|
|
61
|
+
personWrites: boolean;
|
|
62
|
+
/** True when the provider supports the `hogsend connect` OAuth flow. */
|
|
63
|
+
oauth?: boolean;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface AnalyticsProviderMeta {
|
|
67
|
+
/** Registry key, e.g. `"posthog"`, `"segment"`. */
|
|
68
|
+
id: string;
|
|
69
|
+
name: string;
|
|
70
|
+
description?: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The full provider contract. All methods are best-effort wires: a provider
|
|
75
|
+
* must soft-fail (resolve `{}` / no-op) rather than throw on missing
|
|
76
|
+
* credentials or upstream errors — the engine treats analytics as
|
|
77
|
+
* non-load-bearing.
|
|
78
|
+
*/
|
|
79
|
+
export interface AnalyticsProvider extends IdentityProvider {
|
|
80
|
+
meta: AnalyticsProviderMeta;
|
|
81
|
+
capabilities: AnalyticsCapabilities;
|
|
82
|
+
|
|
83
|
+
/** Person WRITE — propagate traits onto the person profile. */
|
|
84
|
+
setPersonProperties(
|
|
85
|
+
opts: { distinctId: string } & PersonPropertiesWrite,
|
|
86
|
+
): Promise<void>;
|
|
87
|
+
|
|
88
|
+
/** Event capture under a distinct id. Fire-and-forget semantics. */
|
|
89
|
+
capture(opts: CaptureOptions): void;
|
|
90
|
+
|
|
91
|
+
/** Flush/teardown any buffered capture queue. */
|
|
92
|
+
shutdown?(): Promise<void>;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Identity helper for authoring providers — exists for symmetry with
|
|
97
|
+
* `defineEmailProvider` / `defineWebhookSource` and to give consumers a
|
|
98
|
+
* single obvious entry point with full type inference.
|
|
99
|
+
*/
|
|
100
|
+
export function defineAnalyticsProvider(
|
|
101
|
+
provider: AnalyticsProvider,
|
|
102
|
+
): AnalyticsProvider {
|
|
103
|
+
return provider;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @deprecated PostHog-shaped service interface, predating the neutral
|
|
108
|
+
* {@link AnalyticsProvider}. Still accepted by `createHogsendClient` (an
|
|
109
|
+
* adapter wraps it) — prefer passing an `AnalyticsProvider`.
|
|
110
|
+
*/
|
|
18
111
|
export interface PostHogService extends IdentityProvider {
|
|
19
112
|
// getPersonProperties is inherited from IdentityProvider (the identity PULL).
|
|
20
113
|
|