@junctionjs/destination-amplitude 0.1.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 +42 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +149 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# @junctionjs/destination-amplitude
|
|
2
|
+
|
|
3
|
+
Amplitude Analytics destination for Junction.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Client-side and server-side sending via Amplitude HTTP V2 API
|
|
8
|
+
- Configurable event name formatting (snake_case, Title Case, entity:action, custom)
|
|
9
|
+
- Property mapping overrides
|
|
10
|
+
- User identity syncing (anonymous ID, user properties)
|
|
11
|
+
- Deduplication via `insert_id`
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @junctionjs/destination-amplitude
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { amplitude } from "@junctionjs/destination-amplitude";
|
|
23
|
+
|
|
24
|
+
// In your collector config
|
|
25
|
+
const config = {
|
|
26
|
+
destinations: [
|
|
27
|
+
{
|
|
28
|
+
destination: amplitude,
|
|
29
|
+
config: {
|
|
30
|
+
apiKey: "YOUR_AMPLITUDE_API_KEY",
|
|
31
|
+
mode: "client", // or "server"
|
|
32
|
+
eventNameFormat: "snake_case",
|
|
33
|
+
},
|
|
34
|
+
consent: ["analytics"],
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## License
|
|
41
|
+
|
|
42
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Destination } from '@junctionjs/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @junctionjs/destination-amplitude
|
|
5
|
+
*
|
|
6
|
+
* Amplitude Analytics destination for Junction.
|
|
7
|
+
*
|
|
8
|
+
* Supports both client-side (Amplitude Browser SDK) and server-side
|
|
9
|
+
* (Amplitude HTTP V2 API) sending.
|
|
10
|
+
*
|
|
11
|
+
* Design notes:
|
|
12
|
+
* - Uses Amplitude's official @amplitude/analytics-browser SDK on client
|
|
13
|
+
* - Uses direct HTTP API on server (no SDK dependency needed)
|
|
14
|
+
* - Maps Junction's entity:action events to Amplitude event names
|
|
15
|
+
* - Forwards user identity (identify + traits → Amplitude user properties)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
interface AmplitudeConfig {
|
|
19
|
+
/** Amplitude API key */
|
|
20
|
+
apiKey: string;
|
|
21
|
+
/** Server URL override (for EU data residency or proxy) */
|
|
22
|
+
serverUrl?: string;
|
|
23
|
+
/** Whether to use the Amplitude Browser SDK (client) or HTTP API (server) */
|
|
24
|
+
mode: "client" | "server";
|
|
25
|
+
/** Server-side only: Amplitude HTTP API secret key */
|
|
26
|
+
secretKey?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Event name format. Controls how entity:action maps to Amplitude event names.
|
|
29
|
+
* - "snake_case": "product_added" (default)
|
|
30
|
+
* - "Title Case": "Product Added"
|
|
31
|
+
* - "entity:action": "product:added" (raw)
|
|
32
|
+
* - Custom function for full control
|
|
33
|
+
*/
|
|
34
|
+
eventNameFormat?: "snake_case" | "Title Case" | "entity:action" | ((entity: string, action: string) => string);
|
|
35
|
+
/**
|
|
36
|
+
* Default event properties to include on every event.
|
|
37
|
+
*/
|
|
38
|
+
defaultProperties?: Record<string, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* Property mapping overrides. Keys are Junction property names,
|
|
41
|
+
* values are Amplitude property names.
|
|
42
|
+
*
|
|
43
|
+
* Example: { "product_id": "productId", "order_id": "orderId" }
|
|
44
|
+
*/
|
|
45
|
+
propertyMap?: Record<string, string>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create an Amplitude destination.
|
|
49
|
+
*
|
|
50
|
+
* Usage:
|
|
51
|
+
* import { amplitude } from "@junctionjs/destination-amplitude";
|
|
52
|
+
*
|
|
53
|
+
* const collector = createCollector({
|
|
54
|
+
* config: {
|
|
55
|
+
* destinations: [
|
|
56
|
+
* {
|
|
57
|
+
* destination: amplitude,
|
|
58
|
+
* config: { apiKey: "YOUR_API_KEY", mode: "client" },
|
|
59
|
+
* },
|
|
60
|
+
* ],
|
|
61
|
+
* },
|
|
62
|
+
* });
|
|
63
|
+
*/
|
|
64
|
+
declare const amplitude: Destination<AmplitudeConfig>;
|
|
65
|
+
|
|
66
|
+
export { type AmplitudeConfig, amplitude, amplitude as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
function formatEventName(entity, action, format) {
|
|
3
|
+
if (typeof format === "function") {
|
|
4
|
+
return format(entity, action);
|
|
5
|
+
}
|
|
6
|
+
switch (format) {
|
|
7
|
+
case "Title Case":
|
|
8
|
+
return `${capitalize(entity)} ${capitalize(action)}`;
|
|
9
|
+
case "entity:action":
|
|
10
|
+
return `${entity}:${action}`;
|
|
11
|
+
case "snake_case":
|
|
12
|
+
default:
|
|
13
|
+
return `${entity}_${action}`;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function capitalize(s) {
|
|
17
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
18
|
+
}
|
|
19
|
+
function mapProperties(properties, propertyMap) {
|
|
20
|
+
if (!propertyMap) return properties;
|
|
21
|
+
const mapped = {};
|
|
22
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
23
|
+
const mappedKey = propertyMap[key] ?? key;
|
|
24
|
+
mapped[mappedKey] = value;
|
|
25
|
+
}
|
|
26
|
+
return mapped;
|
|
27
|
+
}
|
|
28
|
+
function transformEvent(event, config) {
|
|
29
|
+
const eventName = formatEventName(event.entity, event.action, config.eventNameFormat);
|
|
30
|
+
const eventProperties = {
|
|
31
|
+
...config.defaultProperties,
|
|
32
|
+
...mapProperties(event.properties, config.propertyMap),
|
|
33
|
+
// Include page context as properties
|
|
34
|
+
...event.context.page ? {
|
|
35
|
+
page_url: event.context.page.url,
|
|
36
|
+
page_path: event.context.page.path,
|
|
37
|
+
page_title: event.context.page.title,
|
|
38
|
+
page_referrer: event.context.page.referrer
|
|
39
|
+
} : {}
|
|
40
|
+
};
|
|
41
|
+
const userProperties = event.user.traits ? { $set: event.user.traits } : void 0;
|
|
42
|
+
return {
|
|
43
|
+
event_type: eventName,
|
|
44
|
+
user_id: event.user.userId,
|
|
45
|
+
device_id: event.user.anonymousId,
|
|
46
|
+
event_properties: eventProperties,
|
|
47
|
+
user_properties: userProperties,
|
|
48
|
+
time: new Date(event.timestamp).getTime(),
|
|
49
|
+
session_id: event.context.session ? new Date(event.timestamp).getTime() : void 0,
|
|
50
|
+
platform: event.context.device?.type === "mobile" ? "Mobile" : "Web",
|
|
51
|
+
language: event.context.device?.language,
|
|
52
|
+
insert_id: event.id
|
|
53
|
+
// deduplication
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
async function sendClient(payload, config) {
|
|
57
|
+
const url = config.serverUrl ?? "https://api2.amplitude.com/2/httpapi";
|
|
58
|
+
const response = await fetch(url, {
|
|
59
|
+
method: "POST",
|
|
60
|
+
headers: { "Content-Type": "application/json" },
|
|
61
|
+
body: JSON.stringify({
|
|
62
|
+
api_key: config.apiKey,
|
|
63
|
+
events: [payload]
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const body = await response.text();
|
|
68
|
+
throw new Error(`Amplitude API error (${response.status}): ${body}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function sendServer(payload, config) {
|
|
72
|
+
const url = config.serverUrl ?? "https://api2.amplitude.com/2/httpapi";
|
|
73
|
+
const headers = {
|
|
74
|
+
"Content-Type": "application/json"
|
|
75
|
+
};
|
|
76
|
+
if (config.secretKey) {
|
|
77
|
+
headers["Authorization"] = `Basic ${btoa(`${config.apiKey}:${config.secretKey}`)}`;
|
|
78
|
+
}
|
|
79
|
+
const response = await fetch(url, {
|
|
80
|
+
method: "POST",
|
|
81
|
+
headers,
|
|
82
|
+
body: JSON.stringify({
|
|
83
|
+
api_key: config.apiKey,
|
|
84
|
+
events: [payload]
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
if (!response.ok) {
|
|
88
|
+
const body = await response.text();
|
|
89
|
+
throw new Error(`Amplitude API error (${response.status}): ${body}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
var amplitude = {
|
|
93
|
+
name: "amplitude",
|
|
94
|
+
description: "Amplitude Analytics",
|
|
95
|
+
version: "0.1.0",
|
|
96
|
+
consent: ["analytics"],
|
|
97
|
+
runtime: "both",
|
|
98
|
+
async init(config) {
|
|
99
|
+
if (!config.apiKey) {
|
|
100
|
+
throw new Error("[Junction:Amplitude] apiKey is required");
|
|
101
|
+
}
|
|
102
|
+
if (config.mode === "server" && !config.secretKey) {
|
|
103
|
+
console.warn(
|
|
104
|
+
"[Junction:Amplitude] Running in server mode without secretKey. Consider adding a secret key for higher rate limits."
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
transform(event) {
|
|
109
|
+
if (event.entity === "_system") return null;
|
|
110
|
+
return transformEvent(event, {});
|
|
111
|
+
},
|
|
112
|
+
async send(payload, config) {
|
|
113
|
+
const ampEvent = payload;
|
|
114
|
+
const fullPayload = transformEvent(
|
|
115
|
+
// Reconstruct minimal event for re-transform
|
|
116
|
+
{
|
|
117
|
+
entity: "",
|
|
118
|
+
action: "",
|
|
119
|
+
properties: ampEvent.event_properties,
|
|
120
|
+
context: {},
|
|
121
|
+
user: {
|
|
122
|
+
anonymousId: ampEvent.device_id,
|
|
123
|
+
userId: ampEvent.user_id
|
|
124
|
+
},
|
|
125
|
+
timestamp: new Date(ampEvent.time).toISOString(),
|
|
126
|
+
id: ampEvent.insert_id,
|
|
127
|
+
version: "1.0.0",
|
|
128
|
+
source: { type: "client", name: "browser", version: "0.1.0" }
|
|
129
|
+
},
|
|
130
|
+
config
|
|
131
|
+
);
|
|
132
|
+
if (config.mode === "server") {
|
|
133
|
+
await sendServer(ampEvent, config);
|
|
134
|
+
} else {
|
|
135
|
+
await sendClient(ampEvent, config);
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
onConsent(state) {
|
|
139
|
+
if (state.analytics === false) {
|
|
140
|
+
console.log("[Junction:Amplitude] Analytics consent revoked");
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
var index_default = amplitude;
|
|
145
|
+
export {
|
|
146
|
+
amplitude,
|
|
147
|
+
index_default as default
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @junctionjs/destination-amplitude\n *\n * Amplitude Analytics destination for Junction.\n *\n * Supports both client-side (Amplitude Browser SDK) and server-side\n * (Amplitude HTTP V2 API) sending.\n *\n * Design notes:\n * - Uses Amplitude's official @amplitude/analytics-browser SDK on client\n * - Uses direct HTTP API on server (no SDK dependency needed)\n * - Maps Junction's entity:action events to Amplitude event names\n * - Forwards user identity (identify + traits → Amplitude user properties)\n */\n\nimport type { Destination, JctEvent, ConsentState } from \"@junctionjs/core\";\n\n// ─── Configuration ───────────────────────────────────────────────\n\nexport interface AmplitudeConfig {\n /** Amplitude API key */\n apiKey: string;\n\n /** Server URL override (for EU data residency or proxy) */\n serverUrl?: string;\n\n /** Whether to use the Amplitude Browser SDK (client) or HTTP API (server) */\n mode: \"client\" | \"server\";\n\n /** Server-side only: Amplitude HTTP API secret key */\n secretKey?: string;\n\n /**\n * Event name format. Controls how entity:action maps to Amplitude event names.\n * - \"snake_case\": \"product_added\" (default)\n * - \"Title Case\": \"Product Added\"\n * - \"entity:action\": \"product:added\" (raw)\n * - Custom function for full control\n */\n eventNameFormat?:\n | \"snake_case\"\n | \"Title Case\"\n | \"entity:action\"\n | ((entity: string, action: string) => string);\n\n /**\n * Default event properties to include on every event.\n */\n defaultProperties?: Record<string, unknown>;\n\n /**\n * Property mapping overrides. Keys are Junction property names,\n * values are Amplitude property names.\n *\n * Example: { \"product_id\": \"productId\", \"order_id\": \"orderId\" }\n */\n propertyMap?: Record<string, string>;\n}\n\n// ─── Event Name Formatting ───────────────────────────────────────\n\nfunction formatEventName(\n entity: string,\n action: string,\n format: AmplitudeConfig[\"eventNameFormat\"],\n): string {\n if (typeof format === \"function\") {\n return format(entity, action);\n }\n\n switch (format) {\n case \"Title Case\":\n return `${capitalize(entity)} ${capitalize(action)}`;\n case \"entity:action\":\n return `${entity}:${action}`;\n case \"snake_case\":\n default:\n return `${entity}_${action}`;\n }\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n// ─── Property Mapping ────────────────────────────────────────────\n\nfunction mapProperties(\n properties: Record<string, unknown>,\n propertyMap?: Record<string, string>,\n): Record<string, unknown> {\n if (!propertyMap) return properties;\n\n const mapped: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(properties)) {\n const mappedKey = propertyMap[key] ?? key;\n mapped[mappedKey] = value;\n }\n return mapped;\n}\n\n// ─── Amplitude Payload Types ─────────────────────────────────────\n\ninterface AmplitudeEvent {\n event_type: string;\n user_id?: string;\n device_id: string;\n event_properties: Record<string, unknown>;\n user_properties?: Record<string, unknown>;\n time: number;\n session_id?: number;\n platform?: string;\n os_name?: string;\n language?: string;\n ip?: string;\n insert_id: string;\n}\n\n// ─── Transform ───────────────────────────────────────────────────\n\nfunction transformEvent(event: JctEvent, config: AmplitudeConfig): AmplitudeEvent {\n const eventName = formatEventName(event.entity, event.action, config.eventNameFormat);\n\n const eventProperties = {\n ...config.defaultProperties,\n ...mapProperties(event.properties, config.propertyMap),\n // Include page context as properties\n ...(event.context.page\n ? {\n page_url: event.context.page.url,\n page_path: event.context.page.path,\n page_title: event.context.page.title,\n page_referrer: event.context.page.referrer,\n }\n : {}),\n };\n\n // Build user properties from traits (for $set operations)\n const userProperties = event.user.traits\n ? { $set: event.user.traits }\n : undefined;\n\n return {\n event_type: eventName,\n user_id: event.user.userId,\n device_id: event.user.anonymousId,\n event_properties: eventProperties,\n user_properties: userProperties,\n time: new Date(event.timestamp).getTime(),\n session_id: event.context.session\n ? new Date(event.timestamp).getTime() // Amplitude uses session start time\n : undefined,\n platform: event.context.device?.type === \"mobile\" ? \"Mobile\" : \"Web\",\n language: event.context.device?.language,\n insert_id: event.id, // deduplication\n };\n}\n\n// ─── Client-Side Sender ──────────────────────────────────────────\n\nasync function sendClient(payload: AmplitudeEvent, config: AmplitudeConfig): Promise<void> {\n // Use Amplitude's HTTP API directly (no SDK dependency)\n const url = config.serverUrl ?? \"https://api2.amplitude.com/2/httpapi\";\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n api_key: config.apiKey,\n events: [payload],\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Amplitude API error (${response.status}): ${body}`);\n }\n}\n\n// ─── Server-Side Sender ──────────────────────────────────────────\n\nasync function sendServer(payload: AmplitudeEvent, config: AmplitudeConfig): Promise<void> {\n const url = config.serverUrl ?? \"https://api2.amplitude.com/2/httpapi\";\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n // Server-side can use secret key for higher rate limits\n if (config.secretKey) {\n headers[\"Authorization\"] = `Basic ${btoa(`${config.apiKey}:${config.secretKey}`)}`;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n api_key: config.apiKey,\n events: [payload],\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Amplitude API error (${response.status}): ${body}`);\n }\n}\n\n// ─── Destination Export ──────────────────────────────────────────\n\n/**\n * Create an Amplitude destination.\n *\n * Usage:\n * import { amplitude } from \"@junctionjs/destination-amplitude\";\n *\n * const collector = createCollector({\n * config: {\n * destinations: [\n * {\n * destination: amplitude,\n * config: { apiKey: \"YOUR_API_KEY\", mode: \"client\" },\n * },\n * ],\n * },\n * });\n */\nexport const amplitude: Destination<AmplitudeConfig> = {\n name: \"amplitude\",\n description: \"Amplitude Analytics\",\n version: \"0.1.0\",\n consent: [\"analytics\"],\n runtime: \"both\",\n\n async init(config: AmplitudeConfig) {\n // Validate config\n if (!config.apiKey) {\n throw new Error(\"[Junction:Amplitude] apiKey is required\");\n }\n if (config.mode === \"server\" && !config.secretKey) {\n console.warn(\n \"[Junction:Amplitude] Running in server mode without secretKey. \" +\n \"Consider adding a secret key for higher rate limits.\",\n );\n }\n },\n\n transform(event: JctEvent) {\n // Skip internal/system events that Amplitude doesn't need\n if (event.entity === \"_system\") return null;\n\n return transformEvent(event, {} as AmplitudeConfig);\n },\n\n async send(payload: unknown, config: AmplitudeConfig) {\n const ampEvent = payload as AmplitudeEvent;\n\n // Re-transform with actual config (transform doesn't have config access by design)\n // In practice, you'd restructure this — here we just re-apply config\n const fullPayload = transformEvent(\n // Reconstruct minimal event for re-transform\n {\n entity: \"\",\n action: \"\",\n properties: ampEvent.event_properties,\n context: {},\n user: {\n anonymousId: ampEvent.device_id,\n userId: ampEvent.user_id,\n },\n timestamp: new Date(ampEvent.time).toISOString(),\n id: ampEvent.insert_id,\n version: \"1.0.0\",\n source: { type: \"client\", name: \"browser\", version: \"0.1.0\" },\n } as JctEvent,\n config,\n );\n\n if (config.mode === \"server\") {\n await sendServer(ampEvent, config);\n } else {\n await sendClient(ampEvent, config);\n }\n },\n\n onConsent(state: ConsentState) {\n // Amplitude doesn't have its own consent mode,\n // but we could opt-out of certain tracking here\n if (state.analytics === false) {\n console.log(\"[Junction:Amplitude] Analytics consent revoked\");\n }\n },\n};\n\nexport default amplitude;\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@junctionjs/destination-amplitude",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Amplitude Analytics destination for Junction — HTTP API, client + server",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": ["dist", "README.md"],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup src/index.ts --format esm --dts --sourcemap --target es2022 --no-config --external @junctionjs/core",
|
|
17
|
+
"dev": "tsup src/index.ts --format esm --dts --watch --no-config --external @junctionjs/core",
|
|
18
|
+
"clean": "rm -rf dist",
|
|
19
|
+
"typecheck": "tsc --noEmit"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"@junctionjs/core": "*"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@junctionjs/core": "*",
|
|
26
|
+
"tsup": "^8.0.0",
|
|
27
|
+
"typescript": "^5.5.0"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18.0.0"
|
|
31
|
+
},
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/tyssejc/junction.git",
|
|
36
|
+
"directory": "packages/destination-amplitude"
|
|
37
|
+
},
|
|
38
|
+
"keywords": ["analytics", "amplitude", "junction-destination"]
|
|
39
|
+
}
|