node-avo-inspector 1.0.1 → 1.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 +14 -5
- package/dist/AvoDeduplicator.js +2 -2
- package/dist/AvoInspector.d.ts +2 -2
- package/dist/AvoInspector.js +34 -14
- package/dist/AvoInspectorEnv.d.ts +2 -2
- package/dist/AvoNetworkCallsHandler.js +2 -1
- package/dist/AvoSchemaParser.d.ts +1 -0
- package/dist/AvoSchemaParser.js +16 -5
- package/dist/__tests__/TestAvoInspector.js +10 -0
- package/dist/__tests__/TestDeduplicator.js +5 -6
- package/dist/__tests__/TestNetworkCallsHandler.js +2 -2
- package/dist/__tests__/TestNetworkCallsHandlerPublic.js +125 -0
- package/dist/__tests__/TestParsing.js +23 -9
- package/dist/__tests__/constants.d.ts +6 -1
- package/dist/__tests__/constants.js +6 -1
- package/dist/utils.js +2 -2
- package/examples/node-inspector-js/yarn.lock +1 -1
- package/package.json +6 -6
- package/src/AvoInspector.ts +41 -20
- package/src/AvoNetworkCallsHandler.ts +2 -1
- package/src/AvoSchemaParser.ts +24 -7
- package/src/__tests__/TestAvoInspector.ts +20 -1
- package/src/__tests__/TestDeduplicator.ts +1 -3
- package/src/__tests__/TestNetworkCallsHandler.ts +2 -2
- package/src/__tests__/TestNetworkCallsHandlerPublic.ts +137 -0
- package/src/__tests__/TestParsing.ts +32 -9
- package/src/__tests__/constants.ts +6 -1
- package/dist/AvoBatcher.d.ts +0 -17
- package/dist/AvoBatcher.js +0 -31
- package/dist/__tests__/TestBatcher.js +0 -66
- package/dist/__tests__/TestBatcherPublic.d.ts +0 -1
- package/dist/__tests__/TestBatcherPublic.js +0 -60
- package/src/AvoBatcher.ts +0 -60
- package/src/__tests__/TestBatcher.ts +0 -67
- package/src/__tests__/TestBatcherPublic.ts +0 -96
- /package/dist/__tests__/{TestBatcher.d.ts → TestNetworkCallsHandlerPublic.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Avo Inspector SDK for Node.js
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://badge.fury.io/js/node-avo-inspector)
|
|
4
|
+
|
|
5
|
+
This is a quick start guide. For more information about the Inspector project please read the [Inspector SDK Reference](https://www.avo.app/docs/implementation/avo-inspector-sdk-reference) and the [Inspector Setup Guide](https://www.avo.app/docs/implementation/setup-inspector-sdk).
|
|
4
6
|
|
|
5
7
|
# Installation
|
|
6
8
|
|
|
@@ -29,12 +31,19 @@ let inspector = new Inspector.AvoInspector({
|
|
|
29
31
|
});
|
|
30
32
|
```
|
|
31
33
|
|
|
32
|
-
#
|
|
34
|
+
# Integrating with Avo Codegen
|
|
35
|
+
|
|
36
|
+
The setup is lightweight and is covered [in this guide](https://www.avo.app/docs/implementation/start-using-inspector-with-avo-functions).
|
|
37
|
+
|
|
38
|
+
Every event sent with your Codegen after this integration will automatically be sent to Inspector.
|
|
39
|
+
|
|
40
|
+
# Sending event schemas for events reported outside of Codegen
|
|
41
|
+
|
|
42
|
+
Whenever you send tracking event call the following methods:
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
Read more in the [Avo documentation](https://www.avo.app/docs/implementation/inspector/sdk/node)
|
|
44
|
+
Read more in the [Avo documentation](https://www.avo.app/docs/implementation/devs-101#inspecting-events)
|
|
36
45
|
|
|
37
|
-
This method gets actual tracking event parameters, extracts schema automatically and sends it to the
|
|
46
|
+
This method gets actual tracking event parameters, extracts schema automatically and sends it to the Inspector backend.
|
|
38
47
|
It is the easiest way to use the library, just call this method at the same place you call your analytics tools' track methods with the same parameters.
|
|
39
48
|
|
|
40
49
|
```javascript
|
package/dist/AvoDeduplicator.js
CHANGED
|
@@ -46,7 +46,7 @@ class AvoDeduplicator {
|
|
|
46
46
|
if (eventsStorage.hasOwnProperty(otherEventName)) {
|
|
47
47
|
if (otherEventName === eventName) {
|
|
48
48
|
const otherParams = eventsStorage[eventName];
|
|
49
|
-
if (otherParams && utils_1.deepEquals(params, otherParams)) {
|
|
49
|
+
if (otherParams && (0, utils_1.deepEquals)(params, otherParams)) {
|
|
50
50
|
return true;
|
|
51
51
|
}
|
|
52
52
|
}
|
|
@@ -72,7 +72,7 @@ class AvoDeduplicator {
|
|
|
72
72
|
for (const otherEventName in eventsStorage) {
|
|
73
73
|
if (eventsStorage.hasOwnProperty(otherEventName)) {
|
|
74
74
|
const otherParams = eventsStorage[otherEventName];
|
|
75
|
-
if (otherParams && utils_1.deepEquals(params, otherParams)) {
|
|
75
|
+
if (otherParams && (0, utils_1.deepEquals)(params, otherParams)) {
|
|
76
76
|
return true;
|
|
77
77
|
}
|
|
78
78
|
}
|
package/dist/AvoInspector.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { AvoInspectorEnvValueType } from "./AvoInspectorEnv";
|
|
2
|
-
import {
|
|
2
|
+
import { AvoNetworkCallsHandler } from "./AvoNetworkCallsHandler";
|
|
3
3
|
import { AvoDeduplicator } from "./AvoDeduplicator";
|
|
4
4
|
export declare class AvoInspector {
|
|
5
5
|
environment: AvoInspectorEnvValueType;
|
|
6
|
-
|
|
6
|
+
avoNetworkCallsHandler: AvoNetworkCallsHandler;
|
|
7
7
|
avoDeduplicator: AvoDeduplicator;
|
|
8
8
|
apiKey: string;
|
|
9
9
|
version: string;
|
package/dist/AvoInspector.js
CHANGED
|
@@ -3,15 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AvoInspector = void 0;
|
|
4
4
|
const AvoInspectorEnv_1 = require("./AvoInspectorEnv");
|
|
5
5
|
const AvoSchemaParser_1 = require("./AvoSchemaParser");
|
|
6
|
-
const AvoBatcher_1 = require("./AvoBatcher");
|
|
7
6
|
const AvoNetworkCallsHandler_1 = require("./AvoNetworkCallsHandler");
|
|
8
7
|
const AvoDeduplicator_1 = require("./AvoDeduplicator");
|
|
9
8
|
const utils_1 = require("./utils");
|
|
9
|
+
const AvoGuid_1 = require("./AvoGuid");
|
|
10
10
|
const libVersion = require("../package.json").version;
|
|
11
11
|
class AvoInspector {
|
|
12
|
+
static get shouldLog() {
|
|
13
|
+
return this._shouldLog;
|
|
14
|
+
}
|
|
15
|
+
static set shouldLog(enable) {
|
|
16
|
+
this._shouldLog = enable;
|
|
17
|
+
}
|
|
12
18
|
constructor(options) {
|
|
13
19
|
// the constructor does aggressive null/undefined checking because same code paths will be accessible from JS
|
|
14
|
-
if (utils_1.isValueEmpty(options.env)) {
|
|
20
|
+
if ((0, utils_1.isValueEmpty)(options.env)) {
|
|
15
21
|
this.environment = AvoInspectorEnv_1.AvoInspectorEnv.Dev;
|
|
16
22
|
console.warn("[Avo Inspector] No environment provided. Defaulting to dev.");
|
|
17
23
|
}
|
|
@@ -22,13 +28,13 @@ class AvoInspector {
|
|
|
22
28
|
else {
|
|
23
29
|
this.environment = options.env;
|
|
24
30
|
}
|
|
25
|
-
if (utils_1.isValueEmpty(options.apiKey)) {
|
|
31
|
+
if ((0, utils_1.isValueEmpty)(options.apiKey)) {
|
|
26
32
|
throw new Error("[Avo Inspector] No API key provided. Inspector can't operate without API key.");
|
|
27
33
|
}
|
|
28
34
|
else {
|
|
29
35
|
this.apiKey = options.apiKey;
|
|
30
36
|
}
|
|
31
|
-
if (utils_1.isValueEmpty(options.version)) {
|
|
37
|
+
if ((0, utils_1.isValueEmpty)(options.version)) {
|
|
32
38
|
throw new Error("[Avo Inspector] No version provided. Many features of Inspector rely on versioning. Please provide comparable string version, i.e. integer or semantic.");
|
|
33
39
|
}
|
|
34
40
|
else {
|
|
@@ -40,16 +46,9 @@ class AvoInspector {
|
|
|
40
46
|
else {
|
|
41
47
|
AvoInspector._shouldLog = false;
|
|
42
48
|
}
|
|
43
|
-
|
|
44
|
-
this.avoBatcher = new AvoBatcher_1.AvoBatcher(avoNetworkCallsHandler);
|
|
49
|
+
this.avoNetworkCallsHandler = new AvoNetworkCallsHandler_1.AvoNetworkCallsHandler(this.apiKey, this.environment.toString(), options.appName || "", this.version, libVersion);
|
|
45
50
|
this.avoDeduplicator = new AvoDeduplicator_1.AvoDeduplicator();
|
|
46
51
|
}
|
|
47
|
-
static get shouldLog() {
|
|
48
|
-
return this._shouldLog;
|
|
49
|
-
}
|
|
50
|
-
static set shouldLog(enable) {
|
|
51
|
-
this._shouldLog = enable;
|
|
52
|
-
}
|
|
53
52
|
trackSchemaFromEvent(eventName, eventProperties) {
|
|
54
53
|
try {
|
|
55
54
|
if (this.avoDeduplicator.shouldRegisterEvent(eventName, eventProperties, false)) {
|
|
@@ -104,7 +103,28 @@ class AvoInspector {
|
|
|
104
103
|
}
|
|
105
104
|
trackSchemaInternal(eventName, eventSchema, eventId, eventHash) {
|
|
106
105
|
try {
|
|
107
|
-
|
|
106
|
+
const seesionId = AvoGuid_1.AvoGuid.newGuid();
|
|
107
|
+
return this.avoNetworkCallsHandler
|
|
108
|
+
.callInspectorWithBatchBody([
|
|
109
|
+
this.avoNetworkCallsHandler.bodyForSessionStartedCall(seesionId),
|
|
110
|
+
])
|
|
111
|
+
.then(() => {
|
|
112
|
+
if (AvoInspector.shouldLog) {
|
|
113
|
+
console.log("Avo Inspector: session started sent successfully.");
|
|
114
|
+
}
|
|
115
|
+
this.avoNetworkCallsHandler.callInspectorWithBatchBody([
|
|
116
|
+
this.avoNetworkCallsHandler.bodyForEventSchemaCall(seesionId, eventName, eventSchema, eventId, eventHash),
|
|
117
|
+
]).then(() => {
|
|
118
|
+
if (AvoInspector.shouldLog) {
|
|
119
|
+
console.log("Avo Inspector: schema sent successfully.");
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
})
|
|
123
|
+
.catch((err) => {
|
|
124
|
+
if (AvoInspector.shouldLog) {
|
|
125
|
+
console.log("Avo Inspector: schema sending failed: " + err + ".");
|
|
126
|
+
}
|
|
127
|
+
});
|
|
108
128
|
}
|
|
109
129
|
catch (e) {
|
|
110
130
|
console.error("Avo Inspector: something went wrong. Please report to support@avo.app.", e);
|
|
@@ -118,7 +138,7 @@ class AvoInspector {
|
|
|
118
138
|
try {
|
|
119
139
|
if (this.avoDeduplicator.hasSeenEventParams(eventProperties, true)) {
|
|
120
140
|
if (shouldLogIfEnabled && AvoInspector.shouldLog) {
|
|
121
|
-
console.warn("Avo Inspector: WARNING! You are trying to extract schema shape that was just reported by your
|
|
141
|
+
console.warn("Avo Inspector: WARNING! You are trying to extract schema shape that was just reported by your Codegen. " +
|
|
122
142
|
"This is an indicator of duplicate inspector reporting. " +
|
|
123
143
|
"Please reach out to support@avo.app for advice if you are not sure how to handle this.");
|
|
124
144
|
}
|
|
@@ -3,5 +3,5 @@ export declare const AvoInspectorEnv: {
|
|
|
3
3
|
readonly Dev: "dev";
|
|
4
4
|
readonly Staging: "staging";
|
|
5
5
|
};
|
|
6
|
-
export
|
|
7
|
-
export
|
|
6
|
+
export type AvoInspectorEnvType = typeof AvoInspectorEnv;
|
|
7
|
+
export type AvoInspectorEnvValueType = AvoInspectorEnvType[keyof AvoInspectorEnvType];
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AvoNetworkCallsHandler = void 0;
|
|
4
4
|
const AvoGuid_1 = require("./AvoGuid");
|
|
5
5
|
const AvoInspector_1 = require("./AvoInspector");
|
|
6
|
+
const https_1 = require("https");
|
|
6
7
|
class AvoNetworkCallsHandler {
|
|
7
8
|
constructor(apiKey, envName, appName, appVersion, libVersion) {
|
|
8
9
|
this.samplingRate = 1.0;
|
|
@@ -49,7 +50,7 @@ class AvoNetworkCallsHandler {
|
|
|
49
50
|
"Content-Length": Buffer.byteLength(data),
|
|
50
51
|
},
|
|
51
52
|
};
|
|
52
|
-
var req =
|
|
53
|
+
var req = (0, https_1.request)(options, (res) => {
|
|
53
54
|
const chunks = [];
|
|
54
55
|
res.on("data", (data) => chunks.push(data));
|
|
55
56
|
res.on("end", () => {
|
package/dist/AvoSchemaParser.js
CHANGED
|
@@ -56,7 +56,7 @@ class AvoSchemaParser {
|
|
|
56
56
|
}
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
|
-
static
|
|
59
|
+
static getBasicPropType(propValue) {
|
|
60
60
|
let propType = typeof propValue;
|
|
61
61
|
if (propValue == null) {
|
|
62
62
|
return "null";
|
|
@@ -76,15 +76,26 @@ class AvoSchemaParser {
|
|
|
76
76
|
return "boolean";
|
|
77
77
|
}
|
|
78
78
|
else if (propType === "object") {
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
return "object";
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
return "unknown";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
static getPropValueType(propValue) {
|
|
86
|
+
if (isArray(propValue)) {
|
|
87
|
+
//we now know that propValue is an array. get first element in propValue array
|
|
88
|
+
let propElement = propValue[0];
|
|
89
|
+
if (propElement == null) {
|
|
90
|
+
return "list(string)"; // Default to list(string) if the list is empty.
|
|
81
91
|
}
|
|
82
92
|
else {
|
|
83
|
-
|
|
93
|
+
let propElementType = this.getBasicPropType(propElement);
|
|
94
|
+
return `list(${propElementType})`;
|
|
84
95
|
}
|
|
85
96
|
}
|
|
86
97
|
else {
|
|
87
|
-
return
|
|
98
|
+
return this.getBasicPropType(propValue);
|
|
88
99
|
}
|
|
89
100
|
}
|
|
90
101
|
}
|
|
@@ -3,7 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const AvoInspector_1 = require("../AvoInspector");
|
|
4
4
|
const AvoInspectorEnv_1 = require("../AvoInspectorEnv");
|
|
5
5
|
const constants_1 = require("./constants");
|
|
6
|
+
const AvoNetworkCallsHandler_1 = require("../AvoNetworkCallsHandler");
|
|
7
|
+
jest.mock("../AvoNetworkCallsHandler");
|
|
6
8
|
describe("Initialization", () => {
|
|
9
|
+
test("Network Handler is initialized on Inspector init", () => {
|
|
10
|
+
const inspectorVersion = process.env.npm_package_version || "";
|
|
11
|
+
const { apiKey, env, version, appName } = constants_1.defaultOptions;
|
|
12
|
+
let inspector = new AvoInspector_1.AvoInspector(constants_1.defaultOptions);
|
|
13
|
+
inspector.enableLogging(true);
|
|
14
|
+
expect(AvoNetworkCallsHandler_1.AvoNetworkCallsHandler).toHaveBeenCalledTimes(1);
|
|
15
|
+
expect(AvoNetworkCallsHandler_1.AvoNetworkCallsHandler).toHaveBeenCalledWith(apiKey, env, "my-test-app", version, inspectorVersion);
|
|
16
|
+
});
|
|
7
17
|
test("Api Key is set", () => {
|
|
8
18
|
// Given
|
|
9
19
|
const apiKey = "api-key-xxx";
|
|
@@ -28,10 +28,10 @@ describe("Deduplicator", () => {
|
|
|
28
28
|
2: [["str", true]],
|
|
29
29
|
3: { avo: [1.1, 2.2, 3.3] },
|
|
30
30
|
};
|
|
31
|
-
expect(utils_1.deepEquals(testObject, secondObject)).toBe(true);
|
|
32
|
-
expect(utils_1.deepEquals(testObject, Object.assign(Object.assign({}, secondObject), { "4": "4" }))).toBe(false);
|
|
33
|
-
expect(utils_1.deepEquals(testObject, Object.assign(Object.assign({}, secondObject), { 3: Object.assign(Object.assign({}, secondObject[3]), { avo: [1.1] }) }))).toBe(false);
|
|
34
|
-
expect(utils_1.deepEquals(testObject, Object.assign(Object.assign({}, secondObject), { 0: "other string" }))).toBe(false);
|
|
31
|
+
expect((0, utils_1.deepEquals)(testObject, secondObject)).toBe(true);
|
|
32
|
+
expect((0, utils_1.deepEquals)(testObject, Object.assign(Object.assign({}, secondObject), { "4": "4" }))).toBe(false);
|
|
33
|
+
expect((0, utils_1.deepEquals)(testObject, Object.assign(Object.assign({}, secondObject), { 3: Object.assign(Object.assign({}, secondObject[3]), { avo: [1.1] }) }))).toBe(false);
|
|
34
|
+
expect((0, utils_1.deepEquals)(testObject, Object.assign(Object.assign({}, secondObject), { 0: "other string" }))).toBe(false);
|
|
35
35
|
});
|
|
36
36
|
test(`Detects duplications when track in avo and then manually`, () => {
|
|
37
37
|
const shouldRegisterFromAvo = deduplicator.shouldRegisterEvent("Test", testObject, true);
|
|
@@ -53,8 +53,7 @@ describe("Deduplicator", () => {
|
|
|
53
53
|
const avoTrackedSchema = yield inspector._avoFunctionTrackSchemaFromEvent("test", testObject, "eventId", "eventhash");
|
|
54
54
|
const manuallyTrackedSchemaAgain = yield inspector.trackSchemaFromEvent("test", testObject);
|
|
55
55
|
expect(manuallyTrackedSchema.length).toBe(4);
|
|
56
|
-
expect(avoTrackedSchema.length).toBe(
|
|
57
|
-
expect(manuallyTrackedSchemaAgain.length).toBe(4);
|
|
56
|
+
expect(manuallyTrackedSchema.length + avoTrackedSchema.length + manuallyTrackedSchemaAgain.length).toBe(8);
|
|
58
57
|
}));
|
|
59
58
|
test(`Inspector deduplicates only one event when track in avo, manually and then in avo again`, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
59
|
const inspector = new AvoInspector_1.AvoInspector(constants_1.defaultOptions);
|
|
@@ -39,14 +39,14 @@ describe("NetworkCallsHandler", () => {
|
|
|
39
39
|
const body = networkHandler.bodyForSessionStartedCall(constants_1.mockedReturns.SESSION_ID);
|
|
40
40
|
expect(body).toEqual(Object.assign(Object.assign({}, baseBody), { type: "sessionStarted" }));
|
|
41
41
|
});
|
|
42
|
-
test("bodyForEventSchemaCall returns base body + event schema used for event sending from non
|
|
42
|
+
test("bodyForEventSchemaCall returns base body + event schema used for event sending from non Codegen", () => {
|
|
43
43
|
const eventName = "event name";
|
|
44
44
|
const eventProperties = [{ propertyName: "prop0", propertyType: "string" }];
|
|
45
45
|
const body = networkHandler.bodyForEventSchemaCall(constants_1.mockedReturns.SESSION_ID, eventName, eventProperties, null, null);
|
|
46
46
|
expect(body).toEqual(Object.assign(Object.assign({}, baseBody), { type: "event", eventName,
|
|
47
47
|
eventProperties, avoFunction: false, eventId: null, eventHash: null }));
|
|
48
48
|
});
|
|
49
|
-
test("bodyForEventSchemaCall returns base body + event schema used for event sending from
|
|
49
|
+
test("bodyForEventSchemaCall returns base body + event schema used for event sending from Codegen", () => {
|
|
50
50
|
const eventName = "event name";
|
|
51
51
|
const eventId = "event id";
|
|
52
52
|
const eventHash = "event hash";
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const AvoInspector_1 = require("../AvoInspector");
|
|
13
|
+
const AvoNetworkCallsHandler_1 = require("../AvoNetworkCallsHandler");
|
|
14
|
+
const constants_1 = require("./constants");
|
|
15
|
+
describe("AvoNetworkCallsHandler", () => {
|
|
16
|
+
let inspectorCallSpy;
|
|
17
|
+
let inspector;
|
|
18
|
+
const { apiKey, env, version, appName } = constants_1.defaultOptions;
|
|
19
|
+
beforeAll(() => {
|
|
20
|
+
inspector = new AvoInspector_1.AvoInspector(constants_1.defaultOptions);
|
|
21
|
+
inspector.enableLogging(false);
|
|
22
|
+
inspectorCallSpy = jest
|
|
23
|
+
.spyOn(AvoNetworkCallsHandler_1.AvoNetworkCallsHandler.prototype, "callInspectorWithBatchBody");
|
|
24
|
+
inspectorCallSpy.mockImplementation(() => {
|
|
25
|
+
inspector.avoNetworkCallsHandler["samplingRate"] = 0.1;
|
|
26
|
+
return Promise.resolve();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
jest.clearAllMocks();
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
inspector.avoDeduplicator._clearEvents();
|
|
33
|
+
});
|
|
34
|
+
test("handleTrackSchema is called on trackSchemaFromEvent", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
35
|
+
const eventName = "event name";
|
|
36
|
+
const properties = {
|
|
37
|
+
prop0: "",
|
|
38
|
+
prop2: false,
|
|
39
|
+
prop3: 0,
|
|
40
|
+
prop4: 0.0,
|
|
41
|
+
};
|
|
42
|
+
const schema = inspector.extractSchema(properties);
|
|
43
|
+
yield inspector.trackSchemaFromEvent(eventName, properties);
|
|
44
|
+
expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledTimes(2);
|
|
45
|
+
expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toBeCalledWith([
|
|
46
|
+
expect.objectContaining({
|
|
47
|
+
type: "sessionStarted",
|
|
48
|
+
apiKey: apiKey,
|
|
49
|
+
appName: appName,
|
|
50
|
+
appVersion: version,
|
|
51
|
+
libVersion: expect.anything(),
|
|
52
|
+
env: env,
|
|
53
|
+
libPlatform: "node",
|
|
54
|
+
messageId: expect.anything(),
|
|
55
|
+
trackingId: "",
|
|
56
|
+
createdAt: expect.any(String),
|
|
57
|
+
sessionId: expect.anything(),
|
|
58
|
+
samplingRate: 1,
|
|
59
|
+
}),
|
|
60
|
+
]);
|
|
61
|
+
expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledWith([
|
|
62
|
+
expect.objectContaining({
|
|
63
|
+
type: "event",
|
|
64
|
+
apiKey: apiKey,
|
|
65
|
+
appName: appName,
|
|
66
|
+
appVersion: version,
|
|
67
|
+
libVersion: expect.anything(),
|
|
68
|
+
env: env,
|
|
69
|
+
libPlatform: "node",
|
|
70
|
+
messageId: expect.anything(),
|
|
71
|
+
trackingId: "",
|
|
72
|
+
createdAt: expect.anything(),
|
|
73
|
+
sessionId: expect.anything(),
|
|
74
|
+
samplingRate: 0.1,
|
|
75
|
+
}),
|
|
76
|
+
]);
|
|
77
|
+
}));
|
|
78
|
+
test("handleTrackSchema is called on _avoFunctionTrackSchemaFromEvent", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
79
|
+
const eventName = "event name";
|
|
80
|
+
const properties = {
|
|
81
|
+
prop0: "",
|
|
82
|
+
prop2: false,
|
|
83
|
+
prop3: 0,
|
|
84
|
+
prop4: 0.0,
|
|
85
|
+
};
|
|
86
|
+
const eventId = "testId";
|
|
87
|
+
const eventHash = "testHash";
|
|
88
|
+
const schema = inspector.extractSchema(properties);
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
yield inspector._avoFunctionTrackSchemaFromEvent(eventName, properties, eventId, eventHash);
|
|
91
|
+
expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledTimes(2);
|
|
92
|
+
expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toBeCalledWith([
|
|
93
|
+
expect.objectContaining({
|
|
94
|
+
type: "sessionStarted",
|
|
95
|
+
apiKey: apiKey,
|
|
96
|
+
appName: appName,
|
|
97
|
+
appVersion: version,
|
|
98
|
+
libVersion: expect.anything(),
|
|
99
|
+
env: env,
|
|
100
|
+
libPlatform: "node",
|
|
101
|
+
messageId: expect.anything(),
|
|
102
|
+
trackingId: "",
|
|
103
|
+
createdAt: expect.anything(),
|
|
104
|
+
sessionId: expect.anything(),
|
|
105
|
+
samplingRate: 0.1,
|
|
106
|
+
})
|
|
107
|
+
]);
|
|
108
|
+
expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledWith([
|
|
109
|
+
expect.objectContaining({
|
|
110
|
+
type: "event",
|
|
111
|
+
apiKey: apiKey,
|
|
112
|
+
appName: appName,
|
|
113
|
+
appVersion: version,
|
|
114
|
+
libVersion: expect.anything(),
|
|
115
|
+
env: env,
|
|
116
|
+
libPlatform: "node",
|
|
117
|
+
messageId: expect.anything(),
|
|
118
|
+
trackingId: "",
|
|
119
|
+
createdAt: expect.anything(),
|
|
120
|
+
sessionId: expect.anything(),
|
|
121
|
+
samplingRate: 0.1,
|
|
122
|
+
}),
|
|
123
|
+
]);
|
|
124
|
+
}));
|
|
125
|
+
});
|
|
@@ -52,7 +52,7 @@ describe("Schema Parsing", () => {
|
|
|
52
52
|
propertyType: constants_1.type.STRING,
|
|
53
53
|
},
|
|
54
54
|
]);
|
|
55
|
-
expect(res[7].propertyType).toBe(constants_1.type.
|
|
55
|
+
expect(res[7].propertyType).toBe(constants_1.type.STRINGLIST);
|
|
56
56
|
expect(res[7].children).toMatchObject([
|
|
57
57
|
constants_1.type.STRING,
|
|
58
58
|
[
|
|
@@ -77,13 +77,7 @@ describe("Schema Parsing", () => {
|
|
|
77
77
|
// When
|
|
78
78
|
const res = inspector.extractSchema(eventProperties);
|
|
79
79
|
// Then
|
|
80
|
-
expect(res[0].propertyType).toBe(constants_1.type.
|
|
81
|
-
expect(res[0].children).toMatchObject([
|
|
82
|
-
constants_1.type.STRING,
|
|
83
|
-
constants_1.type.BOOL,
|
|
84
|
-
constants_1.type.INT,
|
|
85
|
-
constants_1.type.FLOAT,
|
|
86
|
-
]);
|
|
80
|
+
expect(res[0].propertyType).toBe(constants_1.type.STRINGLIST);
|
|
87
81
|
});
|
|
88
82
|
test("Empty and falsy values are set correctly", () => {
|
|
89
83
|
// Given
|
|
@@ -108,7 +102,27 @@ describe("Schema Parsing", () => {
|
|
|
108
102
|
expect(res[5].propertyType).toBe(constants_1.type.NULL);
|
|
109
103
|
expect(res[6].propertyType).toBe(constants_1.type.OBJECT);
|
|
110
104
|
expect(res[6].children).toMatchObject([]);
|
|
111
|
-
expect(res[7].propertyType).toBe(constants_1.type.
|
|
105
|
+
expect(res[7].propertyType).toBe(constants_1.type.STRINGLIST);
|
|
112
106
|
expect(res[7].children).toMatchObject([]);
|
|
113
107
|
});
|
|
108
|
+
test("List of string returns list(string)", () => {
|
|
109
|
+
// Given
|
|
110
|
+
const eventProperties = {
|
|
111
|
+
prop0: ["a", "b", "c"],
|
|
112
|
+
};
|
|
113
|
+
// When
|
|
114
|
+
const res = inspector.extractSchema(eventProperties);
|
|
115
|
+
// Then
|
|
116
|
+
expect(res[0].propertyType).toBe(constants_1.type.STRINGLIST);
|
|
117
|
+
});
|
|
118
|
+
test("List of multiple types returns list(`firstType`)", () => {
|
|
119
|
+
// Given
|
|
120
|
+
const eventProperties = {
|
|
121
|
+
prop0: [1.2, "two", { "three": 3 }],
|
|
122
|
+
};
|
|
123
|
+
// When
|
|
124
|
+
const res = inspector.extractSchema(eventProperties);
|
|
125
|
+
// Then
|
|
126
|
+
expect(res[0].propertyType).toBe(constants_1.type.FLOATLIST);
|
|
127
|
+
});
|
|
114
128
|
});
|
|
@@ -26,12 +26,17 @@ declare const trackingEndpoint = "https://api.avo.app/inspector/v1/track";
|
|
|
26
26
|
declare const sessionTimeMs: number;
|
|
27
27
|
declare const type: {
|
|
28
28
|
STRING: string;
|
|
29
|
+
STRINGLIST: string;
|
|
29
30
|
INT: string;
|
|
31
|
+
INTLIST: string;
|
|
30
32
|
OBJECT: string;
|
|
33
|
+
OBJECTLIST: string;
|
|
31
34
|
FLOAT: string;
|
|
32
|
-
|
|
35
|
+
FLOATLIST: string;
|
|
33
36
|
BOOL: string;
|
|
37
|
+
BOOLLIST: string;
|
|
34
38
|
NULL: string;
|
|
35
39
|
UNKNOWN: string;
|
|
40
|
+
UNKNOWNLIST: string;
|
|
36
41
|
};
|
|
37
42
|
export { defaultOptions, error, mockedReturns, networkCallType, requestMsg, sessionTimeMs, type, trackingEndpoint, };
|
|
@@ -37,12 +37,17 @@ const sessionTimeMs = 5 * 60 * 1000;
|
|
|
37
37
|
exports.sessionTimeMs = sessionTimeMs;
|
|
38
38
|
const type = {
|
|
39
39
|
STRING: "string",
|
|
40
|
+
STRINGLIST: "list(string)",
|
|
40
41
|
INT: "int",
|
|
42
|
+
INTLIST: "list(int)",
|
|
41
43
|
OBJECT: "object",
|
|
44
|
+
OBJECTLIST: "list(object)",
|
|
42
45
|
FLOAT: "float",
|
|
43
|
-
|
|
46
|
+
FLOATLIST: "list(float)",
|
|
44
47
|
BOOL: "boolean",
|
|
48
|
+
BOOLLIST: "list(boolean)",
|
|
45
49
|
NULL: "null",
|
|
46
50
|
UNKNOWN: "unknown",
|
|
51
|
+
UNKNOWNLIST: "list(unknown)",
|
|
47
52
|
};
|
|
48
53
|
exports.type = type;
|
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.isValueEmpty = void 0;
|
|
4
|
+
exports.deepEquals = deepEquals;
|
|
4
5
|
const isValueEmpty = (value) => {
|
|
5
6
|
return value === null || value === undefined || value.trim().length == 0;
|
|
6
7
|
};
|
|
@@ -39,4 +40,3 @@ function deepEquals(x, y) {
|
|
|
39
40
|
}
|
|
40
41
|
return true;
|
|
41
42
|
}
|
|
42
|
-
exports.deepEquals = deepEquals;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-avo-inspector",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Avo Inspector for Node.js",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"repository": "https://github.com/avohq/node-avo-inspector",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
]
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@types/jest": "^
|
|
40
|
-
"@types/node": "^
|
|
41
|
-
"jest": "^
|
|
42
|
-
"ts-jest": "^
|
|
43
|
-
"typescript": "
|
|
39
|
+
"@types/jest": "^29.5.12",
|
|
40
|
+
"@types/node": "^22.3.0",
|
|
41
|
+
"jest": "^29.7.0",
|
|
42
|
+
"ts-jest": "^29.2.4",
|
|
43
|
+
"typescript": "*"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {}
|
|
46
46
|
}
|