@webiny/telemetry 6.4.0-beta.3 → 6.4.0-beta.4
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/cli.d.ts +0 -1
- package/cli.js +28 -4
- package/package.json +6 -8
- package/react.d.ts +1 -0
- package/react.js +85 -3
- package/sendEvent.js +6 -10
package/cli.d.ts
CHANGED
package/cli.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { globalConfig } from "@webiny/global-config";
|
|
2
2
|
import { isCI } from "ci-info";
|
|
3
|
-
import { WTS } from "wts-client/node
|
|
3
|
+
import { WTS } from "@webiny/wts-client/node";
|
|
4
4
|
import baseSendEvent from "./sendEvent.js";
|
|
5
5
|
import { loadJsonFileSync } from "load-json-file";
|
|
6
6
|
import path from "path";
|
|
7
7
|
|
|
8
|
-
export const sendEvent = async ({ event,
|
|
8
|
+
export const sendEvent = async ({ event, version, properties }) => {
|
|
9
9
|
const shouldSend = isEnabled();
|
|
10
10
|
if (!shouldSend) {
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
// The WTS client reads the machine id from `~/.webiny/config` (user.id field)
|
|
15
|
+
// via the same path globalConfig writes to. No need to pass user explicitly.
|
|
16
|
+
const wts = new WTS({ source: "cli" });
|
|
15
17
|
|
|
16
18
|
const wcpProperties = {};
|
|
17
19
|
const [wcpOrgId, wcpProjectId] = getWcpOrgProjectId();
|
|
@@ -20,15 +22,21 @@ export const sendEvent = async ({ event, user, version, properties }) => {
|
|
|
20
22
|
wcpProperties.wcpProjectId = wcpProjectId;
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
const installationProperties = {};
|
|
26
|
+
const installationId = getInstallationId();
|
|
27
|
+
if (installationId) {
|
|
28
|
+
installationProperties.installation_id = installationId;
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
const packageJsonPath = path.join(import.meta.dirname, "package.json");
|
|
24
32
|
const packageJson = loadJsonFileSync(packageJsonPath);
|
|
25
33
|
|
|
26
34
|
return baseSendEvent({
|
|
27
35
|
event,
|
|
28
|
-
user: user || globalConfig.get("id"),
|
|
29
36
|
properties: {
|
|
30
37
|
...properties,
|
|
31
38
|
...wcpProperties,
|
|
39
|
+
...installationProperties,
|
|
32
40
|
version: version || packageJson.version,
|
|
33
41
|
ci: isCI,
|
|
34
42
|
newUser: Boolean(globalConfig.get("newUser"))
|
|
@@ -46,6 +54,22 @@ const getWcpOrgProjectId = () => {
|
|
|
46
54
|
return [];
|
|
47
55
|
};
|
|
48
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Reads the anonymous per-project installation id from
|
|
59
|
+
* `<project-root>/package.json` → `webiny.installationId`. Generated once at
|
|
60
|
+
* `create-webiny-project` time and tracked in git so it stays stable across
|
|
61
|
+
* machines that share the project. Returns null if the file is missing or
|
|
62
|
+
* unreadable — telemetry events still fire, just without the property.
|
|
63
|
+
*/
|
|
64
|
+
const getInstallationId = () => {
|
|
65
|
+
try {
|
|
66
|
+
const data = loadJsonFileSync(path.join(process.cwd(), "package.json"));
|
|
67
|
+
return typeof data?.webiny?.installationId === "string" ? data.webiny.installationId : null;
|
|
68
|
+
} catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
49
73
|
export const enable = () => {
|
|
50
74
|
globalConfig.set("telemetry", true);
|
|
51
75
|
};
|
package/package.json
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/telemetry",
|
|
3
|
-
"version": "6.4.0-beta.
|
|
3
|
+
"version": "6.4.0-beta.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@webiny/global-config": "6.4.0-beta.
|
|
7
|
+
"@webiny/global-config": "6.4.0-beta.4",
|
|
8
|
+
"@webiny/wts-client": "3.0.2",
|
|
8
9
|
"ci-info": "4.4.0",
|
|
9
10
|
"jsesc": "3.1.0",
|
|
10
11
|
"load-json-file": "7.0.1",
|
|
11
|
-
"strip-ansi": "7.2.0"
|
|
12
|
-
"wts-client": "2.0.0"
|
|
12
|
+
"strip-ansi": "7.2.0"
|
|
13
13
|
},
|
|
14
14
|
"publishConfig": {
|
|
15
|
-
"access": "public"
|
|
16
|
-
|
|
17
|
-
},
|
|
18
|
-
"gitHead": "2e58681d4344024bfb60e6180338e2f154ec87f0"
|
|
15
|
+
"access": "public"
|
|
16
|
+
}
|
|
19
17
|
}
|
package/react.d.ts
CHANGED
package/react.js
CHANGED
|
@@ -1,5 +1,87 @@
|
|
|
1
1
|
import baseSendEvent from "./sendEvent.js";
|
|
2
|
-
import { WTS } from "wts-client/
|
|
2
|
+
import { WTS } from "@webiny/wts-client/web";
|
|
3
|
+
|
|
4
|
+
const STORAGE_MACHINE_ID = "wts_machine_id";
|
|
5
|
+
const STORAGE_PROJECT_ID = "wts_project_id";
|
|
6
|
+
|
|
7
|
+
let wtsInstance = null;
|
|
8
|
+
let projectId = null;
|
|
9
|
+
let distinctId = null;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Resolves the WTS client identity for the admin app.
|
|
13
|
+
*
|
|
14
|
+
* Priority for `distinct_id` (machine_id):
|
|
15
|
+
* 1. URL param `wts_did` on first load. Persisted to localStorage.
|
|
16
|
+
* 2. localStorage (subsequent loads).
|
|
17
|
+
* 3. `process.env.REACT_APP_WEBINY_TELEMETRY_USER_ID` (build-time fallback,
|
|
18
|
+
* set by `SetAdminAppEnvVarsBefore{Build,Watch}` from `~/.webiny/config`).
|
|
19
|
+
*
|
|
20
|
+
* Priority for `project_id` (installation_id):
|
|
21
|
+
* 1. URL param `iid` on first load. Persisted to localStorage.
|
|
22
|
+
* 2. localStorage.
|
|
23
|
+
* 3. `process.env.REACT_APP_WEBINY_INSTALLATION_ID` (build-time fallback,
|
|
24
|
+
* set from `<project>/package.json` → `webiny.installationId`).
|
|
25
|
+
*
|
|
26
|
+
* Attached as a super-property on every admin event so PostHog funnels can
|
|
27
|
+
* group per-install.
|
|
28
|
+
*/
|
|
29
|
+
const initWts = () => {
|
|
30
|
+
if (wtsInstance) {
|
|
31
|
+
return wtsInstance;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
distinctId = process.env.REACT_APP_WEBINY_TELEMETRY_USER_ID;
|
|
35
|
+
projectId = process.env.REACT_APP_WEBINY_INSTALLATION_ID || null;
|
|
36
|
+
|
|
37
|
+
if (typeof window !== "undefined") {
|
|
38
|
+
const params = new URLSearchParams(window.location.search);
|
|
39
|
+
|
|
40
|
+
const fromUrl = params.get("wts_did");
|
|
41
|
+
if (fromUrl) {
|
|
42
|
+
distinctId = fromUrl;
|
|
43
|
+
try {
|
|
44
|
+
window.localStorage.setItem(STORAGE_MACHINE_ID, fromUrl);
|
|
45
|
+
} catch {
|
|
46
|
+
// localStorage unavailable; URL value is used for this session only.
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
try {
|
|
50
|
+
distinctId = window.localStorage.getItem(STORAGE_MACHINE_ID) || distinctId;
|
|
51
|
+
} catch {
|
|
52
|
+
// ignore
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const iidFromUrl = params.get("iid");
|
|
57
|
+
if (iidFromUrl) {
|
|
58
|
+
projectId = iidFromUrl;
|
|
59
|
+
try {
|
|
60
|
+
window.localStorage.setItem(STORAGE_PROJECT_ID, iidFromUrl);
|
|
61
|
+
} catch {
|
|
62
|
+
// ignore
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
try {
|
|
66
|
+
projectId = window.localStorage.getItem(STORAGE_PROJECT_ID) || projectId;
|
|
67
|
+
} catch {
|
|
68
|
+
// env-var value (set above) is used as fallback.
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
wtsInstance = new WTS({ source: "admin", distinctId });
|
|
74
|
+
return wtsInstance;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Returns the machine_id used by admin events, if known. Used by the
|
|
79
|
+
* install/finish CTA to construct the alias handoff URL.
|
|
80
|
+
*/
|
|
81
|
+
export const getMachineId = () => {
|
|
82
|
+
initWts();
|
|
83
|
+
return distinctId || null;
|
|
84
|
+
};
|
|
3
85
|
|
|
4
86
|
export const sendEvent = async (event, properties = {}) => {
|
|
5
87
|
const shouldSend = process.env.REACT_APP_WEBINY_TELEMETRY !== "false";
|
|
@@ -7,7 +89,7 @@ export const sendEvent = async (event, properties = {}) => {
|
|
|
7
89
|
return;
|
|
8
90
|
}
|
|
9
91
|
|
|
10
|
-
const wts =
|
|
92
|
+
const wts = initWts();
|
|
11
93
|
|
|
12
94
|
const wcpProperties = {};
|
|
13
95
|
const [wcpOrgId, wcpProjectId] = getWcpOrgProjectId();
|
|
@@ -18,10 +100,10 @@ export const sendEvent = async (event, properties = {}) => {
|
|
|
18
100
|
|
|
19
101
|
return baseSendEvent({
|
|
20
102
|
event,
|
|
21
|
-
user: process.env.REACT_APP_WEBINY_TELEMETRY_USER_ID,
|
|
22
103
|
properties: {
|
|
23
104
|
...properties,
|
|
24
105
|
...wcpProperties,
|
|
106
|
+
...(projectId ? { project_id: projectId } : {}),
|
|
25
107
|
version: process.env.REACT_APP_WEBINY_VERSION,
|
|
26
108
|
ci: process.env.REACT_APP_IS_CI === "true",
|
|
27
109
|
newUser: process.env.REACT_APP_WEBINY_TELEMETRY_NEW_USER === "true"
|
package/sendEvent.js
CHANGED
|
@@ -4,17 +4,16 @@ import jsesc from "jsesc";
|
|
|
4
4
|
/**
|
|
5
5
|
* The main `sendEvent` function.
|
|
6
6
|
* NOTE: don't use this in your app directly. Instead, use the one from `cli.js` or `react.js` files accordingly.
|
|
7
|
+
*
|
|
8
|
+
* Identity is owned by the WTS instance — `cli.js` reads `~/.webiny/config`,
|
|
9
|
+
* `react.js` reads URL params / localStorage / env. This function only
|
|
10
|
+
* validates and sanitises the event payload before dispatching.
|
|
7
11
|
*/
|
|
8
|
-
export default ({ event,
|
|
9
|
-
// 1. Check for the existence of required base parameters.
|
|
12
|
+
export default ({ event, properties, wts } = {}) => {
|
|
10
13
|
if (!event) {
|
|
11
14
|
throw new Error(`Cannot send event - missing "event" name.`);
|
|
12
15
|
}
|
|
13
16
|
|
|
14
|
-
if (!user) {
|
|
15
|
-
throw new Error(`Cannot send event - missing "user" ID.`);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
17
|
if (!properties) {
|
|
19
18
|
throw new Error(`Cannot send event - missing "properties" object.`);
|
|
20
19
|
}
|
|
@@ -23,7 +22,6 @@ export default ({ event, user, properties, wts } = {}) => {
|
|
|
23
22
|
throw new Error(`Cannot send event - missing "wts" instance.`);
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
// 2. Extract properties and check for existence of required properties.
|
|
27
25
|
if (!properties.version) {
|
|
28
26
|
throw new Error(`Cannot send event - missing "version" property.`);
|
|
29
27
|
}
|
|
@@ -38,7 +36,6 @@ export default ({ event, user, properties, wts } = {}) => {
|
|
|
38
36
|
throw new Error(`Cannot send event - missing "newUser" boolean property.`);
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
// 2. Sanitize properties.
|
|
42
39
|
const sanitizedProperties = {
|
|
43
40
|
...properties,
|
|
44
41
|
newUser: properties.newUser === true ? "yes" : "no",
|
|
@@ -56,6 +53,5 @@ export default ({ event, user, properties, wts } = {}) => {
|
|
|
56
53
|
sanitizedProperties[key] = sanitizedValue;
|
|
57
54
|
}
|
|
58
55
|
|
|
59
|
-
|
|
60
|
-
return wts.trackEvent(user, event, sanitizedProperties);
|
|
56
|
+
return wts.track(event, sanitizedProperties);
|
|
61
57
|
};
|