node-avo-inspector 1.2.0 → 2.0.0-beta.2

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.
Files changed (132) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +270 -4
  3. package/dist/AvoBatchQueue.d.ts +73 -0
  4. package/dist/AvoBatchQueue.js +239 -0
  5. package/dist/AvoDeduplicator.d.ts +15 -6
  6. package/dist/AvoDeduplicator.js +46 -24
  7. package/dist/AvoInspector.d.ts +136 -23
  8. package/dist/AvoInspector.js +777 -109
  9. package/dist/AvoInspectorVersion.d.ts +3 -0
  10. package/dist/AvoInspectorVersion.js +10 -0
  11. package/dist/AvoLog.d.ts +52 -0
  12. package/dist/AvoLog.js +246 -0
  13. package/dist/AvoNetworkCallsHandler.d.ts +55 -8
  14. package/dist/AvoNetworkCallsHandler.js +266 -92
  15. package/dist/AvoSchemaParser.d.ts +6 -0
  16. package/dist/AvoSchemaParser.js +138 -33
  17. package/dist/AvoStreamId.d.ts +2 -1
  18. package/dist/AvoStreamId.js +21 -2
  19. package/dist/eventSpec/AvoEventSpecCache.d.ts +28 -5
  20. package/dist/eventSpec/AvoEventSpecCache.js +66 -11
  21. package/dist/eventSpec/AvoEventSpecFetchTypes.d.ts +50 -18
  22. package/dist/eventSpec/AvoEventSpecFetcher.d.ts +29 -6
  23. package/dist/eventSpec/AvoEventSpecFetcher.js +279 -69
  24. package/dist/eventSpec/EventValidator.d.ts +16 -10
  25. package/dist/eventSpec/EventValidator.js +351 -38
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.js +4 -1
  28. package/dist/utils.d.ts +29 -1
  29. package/dist/utils.js +86 -10
  30. package/package.json +18 -1
  31. package/.claude/scheduled_tasks.lock +0 -1
  32. package/.claude/settings.local.json +0 -11
  33. package/.claude/worktrees/release-1.1.1/LICENSE +0 -21
  34. package/.claude/worktrees/release-1.1.1/README.md +0 -69
  35. package/.claude/worktrees/release-1.1.1/examples/node-inspector-js/index.js +0 -30
  36. package/.claude/worktrees/release-1.1.1/examples/node-inspector-js/package.json +0 -15
  37. package/.claude/worktrees/release-1.1.1/examples/node-inspector-js/yarn.lock +0 -6
  38. package/.claude/worktrees/release-1.1.1/examples/node-inspector-ts/dist/index.js +0 -34
  39. package/.claude/worktrees/release-1.1.1/examples/node-inspector-ts/index.ts +0 -30
  40. package/.claude/worktrees/release-1.1.1/examples/node-inspector-ts/package.json +0 -18
  41. package/.claude/worktrees/release-1.1.1/examples/node-inspector-ts/tsconfig.json +0 -15
  42. package/.claude/worktrees/release-1.1.1/examples/node-inspector-ts/yarn.lock +0 -11
  43. package/.claude/worktrees/release-1.1.1/package-lock.json +0 -4039
  44. package/.claude/worktrees/release-1.1.1/package.json +0 -48
  45. package/.claude/worktrees/release-1.1.1/reason/AvoInspector.rei +0 -11
  46. package/.claude/worktrees/release-1.1.1/reason/NodeAvoInspector.re +0 -27
  47. package/.claude/worktrees/release-1.1.1/src/AvoDeduplicator.ts +0 -146
  48. package/.claude/worktrees/release-1.1.1/src/AvoEncryption.ts +0 -90
  49. package/.claude/worktrees/release-1.1.1/src/AvoGuid.ts +0 -9
  50. package/.claude/worktrees/release-1.1.1/src/AvoInspector.ts +0 -383
  51. package/.claude/worktrees/release-1.1.1/src/AvoInspectorEnv.ts +0 -8
  52. package/.claude/worktrees/release-1.1.1/src/AvoNetworkCallsHandler.ts +0 -267
  53. package/.claude/worktrees/release-1.1.1/src/AvoSchemaParser.ts +0 -115
  54. package/.claude/worktrees/release-1.1.1/src/AvoStreamId.ts +0 -16
  55. package/.claude/worktrees/release-1.1.1/src/__tests__/TestAvoEncryption.ts +0 -515
  56. package/.claude/worktrees/release-1.1.1/src/__tests__/TestAvoEventSpecCache.ts +0 -242
  57. package/.claude/worktrees/release-1.1.1/src/__tests__/TestAvoEventSpecFetcher.ts +0 -241
  58. package/.claude/worktrees/release-1.1.1/src/__tests__/TestAvoInspector.ts +0 -360
  59. package/.claude/worktrees/release-1.1.1/src/__tests__/TestAvoStreamId.ts +0 -72
  60. package/.claude/worktrees/release-1.1.1/src/__tests__/TestDeduplicator.ts +0 -191
  61. package/.claude/worktrees/release-1.1.1/src/__tests__/TestEventValidator.ts +0 -231
  62. package/.claude/worktrees/release-1.1.1/src/__tests__/TestNetworkCallsHandler.ts +0 -179
  63. package/.claude/worktrees/release-1.1.1/src/__tests__/TestNetworkCallsHandlerPublic.ts +0 -208
  64. package/.claude/worktrees/release-1.1.1/src/__tests__/TestParsing.ts +0 -153
  65. package/.claude/worktrees/release-1.1.1/src/__tests__/constants.ts +0 -63
  66. package/.claude/worktrees/release-1.1.1/src/eventSpec/AvoEventSpecCache.ts +0 -109
  67. package/.claude/worktrees/release-1.1.1/src/eventSpec/AvoEventSpecFetchTypes.ts +0 -47
  68. package/.claude/worktrees/release-1.1.1/src/eventSpec/AvoEventSpecFetcher.ts +0 -106
  69. package/.claude/worktrees/release-1.1.1/src/eventSpec/EventValidator.ts +0 -74
  70. package/.claude/worktrees/release-1.1.1/src/index.ts +0 -2
  71. package/.claude/worktrees/release-1.1.1/src/utils.ts +0 -49
  72. package/.claude/worktrees/release-1.1.1/tsconfig.json +0 -13
  73. package/.claude/worktrees/release-1.1.1/yarn.lock +0 -2310
  74. package/.github/workflows/claude.yml +0 -55
  75. package/dist/__tests__/TestAvoEncryption.d.ts +0 -1
  76. package/dist/__tests__/TestAvoEncryption.js +0 -288
  77. package/dist/__tests__/TestAvoEventSpecCache.d.ts +0 -1
  78. package/dist/__tests__/TestAvoEventSpecCache.js +0 -194
  79. package/dist/__tests__/TestAvoEventSpecFetcher.d.ts +0 -1
  80. package/dist/__tests__/TestAvoEventSpecFetcher.js +0 -219
  81. package/dist/__tests__/TestAvoInspector.d.ts +0 -1
  82. package/dist/__tests__/TestAvoInspector.js +0 -291
  83. package/dist/__tests__/TestAvoStreamId.d.ts +0 -1
  84. package/dist/__tests__/TestAvoStreamId.js +0 -55
  85. package/dist/__tests__/TestDeduplicator.d.ts +0 -1
  86. package/dist/__tests__/TestDeduplicator.js +0 -102
  87. package/dist/__tests__/TestEventValidator.d.ts +0 -1
  88. package/dist/__tests__/TestEventValidator.js +0 -196
  89. package/dist/__tests__/TestNetworkCallsHandler.d.ts +0 -1
  90. package/dist/__tests__/TestNetworkCallsHandler.js +0 -86
  91. package/dist/__tests__/TestNetworkCallsHandlerPublic.d.ts +0 -1
  92. package/dist/__tests__/TestNetworkCallsHandlerPublic.js +0 -160
  93. package/dist/__tests__/TestParsing.d.ts +0 -1
  94. package/dist/__tests__/TestParsing.js +0 -128
  95. package/dist/__tests__/constants.d.ts +0 -42
  96. package/dist/__tests__/constants.js +0 -53
  97. package/examples/node-inspector-js/index.js +0 -30
  98. package/examples/node-inspector-js/package.json +0 -15
  99. package/examples/node-inspector-js/yarn.lock +0 -6
  100. package/examples/node-inspector-ts/dist/index.js +0 -34
  101. package/examples/node-inspector-ts/index.ts +0 -30
  102. package/examples/node-inspector-ts/package.json +0 -18
  103. package/examples/node-inspector-ts/tsconfig.json +0 -15
  104. package/examples/node-inspector-ts/yarn.lock +0 -11
  105. package/reason/AvoInspector.rei +0 -11
  106. package/reason/NodeAvoInspector.re +0 -27
  107. package/src/AvoDeduplicator.ts +0 -150
  108. package/src/AvoEncryption.ts +0 -90
  109. package/src/AvoGuid.ts +0 -9
  110. package/src/AvoInspector.ts +0 -498
  111. package/src/AvoInspectorEnv.ts +0 -8
  112. package/src/AvoNetworkCallsHandler.ts +0 -340
  113. package/src/AvoSchemaParser.ts +0 -115
  114. package/src/AvoStreamId.ts +0 -16
  115. package/src/__tests__/TestAvoEncryption.ts +0 -515
  116. package/src/__tests__/TestAvoEventSpecCache.ts +0 -242
  117. package/src/__tests__/TestAvoEventSpecFetcher.ts +0 -279
  118. package/src/__tests__/TestAvoInspector.ts +0 -376
  119. package/src/__tests__/TestAvoStreamId.ts +0 -72
  120. package/src/__tests__/TestDeduplicator.ts +0 -191
  121. package/src/__tests__/TestEventValidator.ts +0 -231
  122. package/src/__tests__/TestNetworkCallsHandler.ts +0 -181
  123. package/src/__tests__/TestNetworkCallsHandlerPublic.ts +0 -208
  124. package/src/__tests__/TestParsing.ts +0 -153
  125. package/src/__tests__/constants.ts +0 -63
  126. package/src/eventSpec/AvoEventSpecCache.ts +0 -119
  127. package/src/eventSpec/AvoEventSpecFetchTypes.ts +0 -47
  128. package/src/eventSpec/AvoEventSpecFetcher.ts +0 -186
  129. package/src/eventSpec/EventValidator.ts +0 -74
  130. package/src/index.ts +0 -2
  131. package/src/utils.ts +0 -49
  132. package/tsconfig.json +0 -13
@@ -1,196 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const EventValidator_1 = require("../eventSpec/EventValidator");
4
- // We need to mock safe-regex2 for some tests
5
- jest.mock("safe-regex2", () => {
6
- const actual = jest.requireActual("safe-regex2");
7
- return {
8
- __esModule: true,
9
- default: actual.default || actual,
10
- _mockable: true,
11
- };
12
- });
13
- describe("EventValidator", () => {
14
- let validator;
15
- beforeEach(() => {
16
- validator = new EventValidator_1.EventValidator();
17
- jest.spyOn(console, "warn").mockImplementation(() => { });
18
- });
19
- afterEach(() => {
20
- jest.restoreAllMocks();
21
- });
22
- describe("type validation", () => {
23
- test("passes when property types match spec", () => {
24
- const spec = {
25
- eventName: "click",
26
- properties: [
27
- { propertyName: "target", propertyType: "string" },
28
- { propertyName: "count", propertyType: "int" },
29
- ],
30
- };
31
- const eventProperties = [
32
- { propertyName: "target", propertyType: "string" },
33
- { propertyName: "count", propertyType: "int" },
34
- ];
35
- const results = validator.validate(spec, eventProperties, "evt-1");
36
- // All properties passed type check, so failedEventIds should be empty
37
- expect(results.every((r) => r.failedEventIds.length === 0)).toBe(true);
38
- // Bandwidth optimization: passedEventIds cleared because passed >= failed for each property
39
- expect(results.every((r) => r.passedEventIds.length === 0)).toBe(true);
40
- });
41
- test("fails when property type does not match spec", () => {
42
- const spec = {
43
- eventName: "click",
44
- properties: [{ propertyName: "count", propertyType: "int" }],
45
- };
46
- const eventProperties = [
47
- { propertyName: "count", propertyType: "string" },
48
- ];
49
- const results = validator.validate(spec, eventProperties, "evt-2");
50
- const countResult = results.find((r) => r.propertyName === "count");
51
- expect(countResult === null || countResult === void 0 ? void 0 : countResult.failedEventIds).toContain("evt-2");
52
- expect(countResult === null || countResult === void 0 ? void 0 : countResult.passedEventIds).not.toContain("evt-2");
53
- });
54
- test("fails for missing required properties", () => {
55
- const spec = {
56
- eventName: "click",
57
- properties: [
58
- { propertyName: "target", propertyType: "string" },
59
- { propertyName: "count", propertyType: "int" },
60
- ],
61
- };
62
- const eventProperties = [
63
- { propertyName: "target", propertyType: "string" },
64
- // count is missing
65
- ];
66
- const results = validator.validate(spec, eventProperties, "evt-3");
67
- const countResult = results.find((r) => r.propertyName === "count");
68
- expect(countResult === null || countResult === void 0 ? void 0 : countResult.failedEventIds).toContain("evt-3");
69
- });
70
- });
71
- describe("regex validation", () => {
72
- test("passes when value matches safe regex pattern (type match)", () => {
73
- const spec = {
74
- eventName: "navigate",
75
- properties: [
76
- {
77
- propertyName: "url",
78
- propertyType: "string",
79
- regex: "^https://",
80
- },
81
- ],
82
- };
83
- const eventProperties = [
84
- { propertyName: "url", propertyType: "string", propertyValue: "https://example.com" },
85
- ];
86
- const results = validator.validate(spec, eventProperties, "evt-4");
87
- const urlResult = results.find((r) => r.propertyName === "url");
88
- // Type matches and regex matches, property passed. Bandwidth optimization: passedEventIds cleared
89
- // because passed count (1) >= failed count (0)
90
- expect(urlResult === null || urlResult === void 0 ? void 0 : urlResult.failedEventIds).toEqual([]);
91
- });
92
- test("fails when value does not match safe regex pattern", () => {
93
- const spec = {
94
- eventName: "navigate",
95
- properties: [
96
- {
97
- propertyName: "url",
98
- propertyType: "string",
99
- regex: "^https://",
100
- },
101
- ],
102
- };
103
- const eventProperties = [
104
- { propertyName: "url", propertyType: "string", propertyValue: "http://example.com" },
105
- ];
106
- const results = validator.validate(spec, eventProperties, "evt-regex-fail");
107
- const urlResult = results.find((r) => r.propertyName === "url");
108
- expect(urlResult === null || urlResult === void 0 ? void 0 : urlResult.failedEventIds).toContain("evt-regex-fail");
109
- expect(urlResult === null || urlResult === void 0 ? void 0 : urlResult.passedEventIds).not.toContain("evt-regex-fail");
110
- });
111
- test("logs warning and passes type check when regex syntax is invalid", () => {
112
- const spec = {
113
- eventName: "filter",
114
- properties: [
115
- {
116
- propertyName: "pattern",
117
- propertyType: "string",
118
- regex: "[invalid",
119
- },
120
- ],
121
- };
122
- const eventProperties = [
123
- { propertyName: "pattern", propertyType: "string", propertyValue: "anything" },
124
- ];
125
- const results = validator.validate(spec, eventProperties, "evt-bad-regex");
126
- const patternResult = results.find((r) => r.propertyName === "pattern");
127
- // Invalid regex is caught, property still passes type check
128
- expect(patternResult === null || patternResult === void 0 ? void 0 : patternResult.failedEventIds).toEqual([]);
129
- expect(console.warn).toHaveBeenCalledWith(expect.stringContaining("[Avo Inspector] Warning"));
130
- });
131
- test("skips unsafe regex patterns with warning", () => {
132
- const spec = {
133
- eventName: "search",
134
- properties: [
135
- {
136
- propertyName: "query",
137
- propertyType: "string",
138
- // Catastrophic backtracking pattern
139
- regex: "(a+)+$",
140
- },
141
- ],
142
- };
143
- const eventProperties = [
144
- { propertyName: "query", propertyType: "string", propertyValue: "aaa" },
145
- ];
146
- const results = validator.validate(spec, eventProperties, "evt-5");
147
- // Unsafe regex should be skipped, property still passes type check
148
- const queryResult = results.find((r) => r.propertyName === "query");
149
- // Bandwidth optimization: passedEventIds cleared because passed count >= failed count
150
- expect(queryResult === null || queryResult === void 0 ? void 0 : queryResult.failedEventIds).toEqual([]);
151
- expect(console.warn).toHaveBeenCalledWith(expect.stringContaining("[Avo Inspector] Warning"));
152
- });
153
- });
154
- describe("extra/unexpected properties", () => {
155
- test("ignores properties present in event but not in the spec", () => {
156
- const spec = {
157
- eventName: "click",
158
- properties: [
159
- { propertyName: "target", propertyType: "string" },
160
- ],
161
- };
162
- const eventProperties = [
163
- { propertyName: "target", propertyType: "string" },
164
- { propertyName: "extraProp", propertyType: "int" },
165
- { propertyName: "anotherExtra", propertyType: "boolean" },
166
- ];
167
- const results = validator.validate(spec, eventProperties, "evt-extra");
168
- // Only spec properties get results — extra properties are not reported
169
- expect(results).toHaveLength(1);
170
- expect(results[0].propertyName).toBe("target");
171
- expect(results.find((r) => r.propertyName === "extraProp")).toBeUndefined();
172
- expect(results.find((r) => r.propertyName === "anotherExtra")).toBeUndefined();
173
- });
174
- });
175
- describe("bandwidth optimization", () => {
176
- test("returns passedEventIds only when strictly smaller than failedEventIds", () => {
177
- const spec = {
178
- eventName: "click",
179
- properties: [{ propertyName: "target", propertyType: "string" }],
180
- };
181
- // Single pass
182
- const passResults = validator.validate(spec, [{ propertyName: "target", propertyType: "string" }], "evt-pass");
183
- const passResult = passResults.find((r) => r.propertyName === "target");
184
- // When there's only passed and no failed, passedEventIds count (1) > failedEventIds count (0)
185
- // So passedEventIds is NOT strictly smaller - it should be returned
186
- // But the optimization says: return passedEventIds ONLY when strictly smaller than failedEventIds
187
- // So when passedEventIds.length >= failedEventIds.length, we clear passedEventIds
188
- expect(passResult === null || passResult === void 0 ? void 0 : passResult.passedEventIds).toEqual([]);
189
- // Single fail
190
- const failResults = validator.validate(spec, [{ propertyName: "target", propertyType: "int" }], "evt-fail");
191
- const failResult = failResults.find((r) => r.propertyName === "target");
192
- // failedEventIds has 1, passedEventIds has 0 -> passedEventIds is strictly smaller, return it
193
- expect(failResult === null || failResult === void 0 ? void 0 : failResult.failedEventIds).toContain("evt-fail");
194
- });
195
- });
196
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,86 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const AvoGuid_1 = require("../AvoGuid");
4
- const AvoNetworkCallsHandler_1 = require("../AvoNetworkCallsHandler");
5
- const constants_1 = require("./constants");
6
- const inspectorVersion = process.env.npm_package_version || "";
7
- describe("NetworkCallsHandler", () => {
8
- const { apiKey, env, version } = constants_1.defaultOptions;
9
- const appName = "";
10
- let networkHandler;
11
- let baseBody;
12
- const now = new Date();
13
- beforeAll(() => {
14
- // @ts-ignore
15
- jest.spyOn(global, "Date").mockImplementation(() => now);
16
- jest
17
- .spyOn(AvoGuid_1.AvoGuid, "newGuid")
18
- .mockImplementation(() => constants_1.mockedReturns.GUID);
19
- networkHandler = new AvoNetworkCallsHandler_1.AvoNetworkCallsHandler(apiKey, env, "", version, inspectorVersion);
20
- baseBody = {
21
- apiKey,
22
- appName,
23
- appVersion: version,
24
- libVersion: inspectorVersion,
25
- env,
26
- libPlatform: "node",
27
- messageId: constants_1.mockedReturns.GUID,
28
- trackingId: "",
29
- sessionId: "",
30
- anonymousId: "",
31
- createdAt: new Date().toISOString(),
32
- samplingRate: 1.0,
33
- };
34
- });
35
- afterEach(() => {
36
- jest.clearAllMocks();
37
- });
38
- test("bodyForEventSchemaCall returns base body + event schema used for event sending from non Codegen", () => {
39
- const eventName = "event name";
40
- const eventProperties = [{ propertyName: "prop0", propertyType: "string" }];
41
- const body = networkHandler.bodyForEventSchemaCall("", eventName, eventProperties, null, null);
42
- expect(body).toEqual(Object.assign(Object.assign({}, baseBody), { anonymousId: "", type: "event", eventName,
43
- eventProperties, avoFunction: false, eventId: null, eventHash: null }));
44
- });
45
- test("bodyForEventSchemaCall returns base body + event schema used for event sending from Codegen", () => {
46
- const eventName = "event name";
47
- const eventId = "event id";
48
- const eventHash = "event hash";
49
- const eventProperties = [{ propertyName: "prop0", propertyType: "string" }];
50
- const body = networkHandler.bodyForEventSchemaCall("", eventName, eventProperties, eventId, eventHash);
51
- expect(body).toEqual(Object.assign(Object.assign({}, baseBody), { anonymousId: "", type: "event", eventName,
52
- eventProperties, avoFunction: true, eventId,
53
- eventHash }));
54
- });
55
- test("bodyForEventSchemaCall uses streamId as anonymousId", () => {
56
- const eventName = "event name";
57
- const streamId = "user-123";
58
- const eventProperties = [{ propertyName: "prop0", propertyType: "string" }];
59
- const body = networkHandler.bodyForEventSchemaCall(streamId, eventName, eventProperties, null, null);
60
- expect(body.anonymousId).toBe("user-123");
61
- });
62
- test("bodyForEventSchemaCall with rawEventProperties passes them through (no encryption in dev without key)", () => {
63
- const eventName = "event name";
64
- const eventProperties = [{ propertyName: "prop0", propertyType: "string" }];
65
- const rawEventProperties = { prop0: "hello" };
66
- const body = networkHandler.bodyForEventSchemaCall("", eventName, eventProperties, null, null, rawEventProperties);
67
- // Without a publicEncryptionKey, encryption is not triggered,
68
- // so eventProperties should be the plain schema (not encrypted)
69
- expect(body.eventProperties).toEqual(eventProperties);
70
- expect(body.type).toBe("event");
71
- expect(body.eventName).toBe(eventName);
72
- });
73
- test("base body includes publicEncryptionKey when handler is constructed with one", () => {
74
- const handlerWithKey = new AvoNetworkCallsHandler_1.AvoNetworkCallsHandler(apiKey, env, "", version, inspectorVersion, "test-public-key-abc");
75
- const eventName = "event name";
76
- const eventProperties = [{ propertyName: "prop0", propertyType: "string" }];
77
- const body = handlerWithKey.bodyForEventSchemaCall("", eventName, eventProperties, null, null);
78
- expect(body.publicEncryptionKey).toBe("test-public-key-abc");
79
- });
80
- test("base body does not include publicEncryptionKey when handler is constructed without one", () => {
81
- const eventName = "event name";
82
- const eventProperties = [{ propertyName: "prop0", propertyType: "string" }];
83
- const body = networkHandler.bodyForEventSchemaCall("", eventName, eventProperties, null, null);
84
- expect(body.publicEncryptionKey).toBeUndefined();
85
- });
86
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,160 +0,0 @@
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 consoleLogSpy;
18
- let inspector;
19
- const { apiKey, env, version, appName } = constants_1.defaultOptions;
20
- const eventName = "event name";
21
- const properties = {
22
- prop0: "",
23
- prop2: false,
24
- prop3: 0,
25
- prop4: 0.0,
26
- };
27
- const happyPathInspectorCall = () => {
28
- return Promise.resolve();
29
- };
30
- beforeAll(() => {
31
- inspector = new AvoInspector_1.AvoInspector(constants_1.defaultOptions);
32
- inspector.enableLogging(true);
33
- inspectorCallSpy = jest
34
- .spyOn(AvoNetworkCallsHandler_1.AvoNetworkCallsHandler.prototype, "callInspectorWithBatchBody");
35
- consoleLogSpy = jest.spyOn(console, "log").mockImplementation(() => { });
36
- });
37
- beforeEach(() => {
38
- inspectorCallSpy.mockImplementation(happyPathInspectorCall);
39
- });
40
- afterEach(() => {
41
- jest.clearAllMocks();
42
- // @ts-ignore
43
- inspector.avoDeduplicator._clearEvents();
44
- });
45
- test("trackSchemaFromEvent sends only event call (no sessionStarted)", () => __awaiter(void 0, void 0, void 0, function* () {
46
- yield inspector.trackSchemaFromEvent(eventName, properties);
47
- // Should be called once (event only, no sessionStarted)
48
- expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledTimes(1);
49
- expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledWith([
50
- expect.objectContaining({
51
- type: "event",
52
- apiKey: apiKey,
53
- appName: appName,
54
- appVersion: version,
55
- libVersion: expect.anything(),
56
- env: env,
57
- libPlatform: "node",
58
- messageId: expect.anything(),
59
- anonymousId: "",
60
- createdAt: expect.any(String),
61
- samplingRate: 1,
62
- }),
63
- ]);
64
- }));
65
- test("trackSchemaFromEvent with streamId sets anonymousId to streamId", () => __awaiter(void 0, void 0, void 0, function* () {
66
- yield inspector.trackSchemaFromEvent(eventName, properties, "user-stream-123");
67
- expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledTimes(1);
68
- expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledWith([
69
- expect.objectContaining({
70
- type: "event",
71
- anonymousId: "user-stream-123",
72
- }),
73
- ]);
74
- }));
75
- test("trackSchemaFromEvent without streamId sets anonymousId to empty string", () => __awaiter(void 0, void 0, void 0, function* () {
76
- yield inspector.trackSchemaFromEvent(eventName, properties);
77
- expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledTimes(1);
78
- expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledWith([
79
- expect.objectContaining({
80
- anonymousId: "",
81
- }),
82
- ]);
83
- }));
84
- test("trackSchemaFromEvent with streamId containing ':' logs warning", () => __awaiter(void 0, void 0, void 0, function* () {
85
- const consoleWarnSpy = jest.spyOn(console, "warn").mockImplementation(() => { });
86
- yield inspector.trackSchemaFromEvent(eventName, properties, "invalid:stream");
87
- expect(consoleWarnSpy).toHaveBeenCalledWith("[Avo Inspector] Warning: streamId contains ':' which is not supported");
88
- consoleWarnSpy.mockRestore();
89
- }));
90
- test("_avoFunctionTrackSchemaFromEvent sends only event call (no sessionStarted)", () => __awaiter(void 0, void 0, void 0, function* () {
91
- const eventId = "testId";
92
- const eventHash = "testHash";
93
- // @ts-ignore
94
- yield inspector._avoFunctionTrackSchemaFromEvent(eventName, properties, eventId, eventHash);
95
- // Should be called once (event only, no sessionStarted)
96
- expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledTimes(1);
97
- expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledWith([
98
- expect.objectContaining({
99
- type: "event",
100
- apiKey: apiKey,
101
- appName: appName,
102
- appVersion: version,
103
- libVersion: expect.anything(),
104
- env: env,
105
- libPlatform: "node",
106
- messageId: expect.anything(),
107
- anonymousId: "",
108
- createdAt: expect.any(String),
109
- }),
110
- ]);
111
- }));
112
- test("an error is logged if event schema call fails and AvoInspector.shouldLog is true", () => __awaiter(void 0, void 0, void 0, function* () {
113
- const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
114
- inspectorCallSpy.mockRejectedValueOnce('Network error');
115
- yield inspector.trackSchemaFromEvent(eventName, properties);
116
- expect(consoleErrorSpy).toHaveBeenCalledWith('Avo Inspector: schema sending failed: Network error.');
117
- consoleErrorSpy.mockRestore();
118
- }));
119
- test("_avoFunctionTrackSchemaFromEvent passes empty string as anonymousId", () => __awaiter(void 0, void 0, void 0, function* () {
120
- const eventId = "testId";
121
- const eventHash = "testHash";
122
- // @ts-ignore
123
- yield inspector._avoFunctionTrackSchemaFromEvent(eventName, properties, eventId, eventHash);
124
- expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledWith([
125
- expect.objectContaining({
126
- anonymousId: "",
127
- }),
128
- ]);
129
- }));
130
- test("trackSchemaFromEvent with streamId containing ':' still sends the event", () => __awaiter(void 0, void 0, void 0, function* () {
131
- const consoleWarnSpy = jest.spyOn(console, "warn").mockImplementation(() => { });
132
- yield inspector.trackSchemaFromEvent(eventName, properties, "bad:stream");
133
- // Warning is logged
134
- expect(consoleWarnSpy).toHaveBeenCalledWith("[Avo Inspector] Warning: streamId contains ':' which is not supported");
135
- // Event is still sent despite the warning
136
- expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledTimes(1);
137
- expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledWith([
138
- expect.objectContaining({
139
- type: "event",
140
- anonymousId: "bad:stream",
141
- }),
142
- ]);
143
- consoleWarnSpy.mockRestore();
144
- }));
145
- test("same event with different streamIds is not deduplicated", () => __awaiter(void 0, void 0, void 0, function* () {
146
- yield inspector.trackSchemaFromEvent(eventName, properties, "stream-a");
147
- yield inspector.trackSchemaFromEvent(eventName, properties, "stream-b");
148
- expect(inspector.avoNetworkCallsHandler.callInspectorWithBatchBody).toHaveBeenCalledTimes(2);
149
- }));
150
- test("trackSchemaFromEvent rejection contains the expected error string", () => __awaiter(void 0, void 0, void 0, function* () {
151
- const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => { });
152
- // Force the catch block in trackSchemaFromEvent by making extractSchema throw
153
- jest.spyOn(inspector, "extractSchema").mockImplementation(() => {
154
- throw new Error("test explosion");
155
- });
156
- yield expect(inspector.trackSchemaFromEvent(eventName, properties)).rejects.toBe("Avo Inspector: something went wrong. Please report to support@avo.app.");
157
- consoleErrorSpy.mockRestore();
158
- inspector.extractSchema.mockRestore();
159
- }));
160
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,128 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const AvoInspector_1 = require("../AvoInspector");
4
- const constants_1 = require("./constants");
5
- describe("Schema Parsing", () => {
6
- const inspector = new AvoInspector_1.AvoInspector(constants_1.defaultOptions);
7
- beforeAll(() => {
8
- inspector.enableLogging(false);
9
- });
10
- test("Empty array returned if eventProperties are not set", () => {
11
- // @ts-ignore
12
- const schema = inspector.extractSchema();
13
- expect(schema).toEqual([]);
14
- });
15
- test("Property types and names are set", () => {
16
- // Given
17
- const eventProperties = {
18
- prop0: true,
19
- prop1: 1,
20
- prop2: "str",
21
- prop3: 0.5,
22
- prop4: undefined,
23
- prop5: null,
24
- prop6: { an: "object" },
25
- prop7: [
26
- "a",
27
- "list",
28
- {
29
- "obj in list": true,
30
- "int field": 1,
31
- },
32
- ["another", "list"],
33
- [1, 2],
34
- ],
35
- };
36
- // When
37
- const res = inspector.extractSchema(eventProperties);
38
- // Then
39
- res.forEach(({ propertyName }, index) => {
40
- expect(propertyName).toBe(`prop${index}`);
41
- });
42
- expect(res[0].propertyType).toBe(constants_1.type.BOOL);
43
- expect(res[1].propertyType).toBe(constants_1.type.INT);
44
- expect(res[2].propertyType).toBe(constants_1.type.STRING);
45
- expect(res[3].propertyType).toBe(constants_1.type.FLOAT);
46
- expect(res[4].propertyType).toBe(constants_1.type.NULL);
47
- expect(res[5].propertyType).toBe(constants_1.type.NULL);
48
- expect(res[6].propertyType).toBe(constants_1.type.OBJECT);
49
- expect(res[6].children).toMatchObject([
50
- {
51
- propertyName: "an",
52
- propertyType: constants_1.type.STRING,
53
- },
54
- ]);
55
- expect(res[7].propertyType).toBe(constants_1.type.STRINGLIST);
56
- expect(res[7].children).toMatchObject([
57
- constants_1.type.STRING,
58
- [
59
- {
60
- propertyName: "obj in list",
61
- propertyType: constants_1.type.BOOL,
62
- },
63
- {
64
- propertyName: "int field",
65
- propertyType: constants_1.type.INT,
66
- },
67
- ],
68
- [constants_1.type.STRING],
69
- [constants_1.type.INT],
70
- ]);
71
- });
72
- test("Duplicated values are removed", () => {
73
- // Given
74
- const eventProperties = {
75
- prop0: ["true", "false", true, 10, "true", true, 11, 10, 0.1, 0.1],
76
- };
77
- // When
78
- const res = inspector.extractSchema(eventProperties);
79
- // Then
80
- expect(res[0].propertyType).toBe(constants_1.type.STRINGLIST);
81
- });
82
- test("Empty and falsy values are set correctly", () => {
83
- // Given
84
- const eventProperties = {
85
- prop0: false,
86
- prop1: 0,
87
- prop2: "",
88
- prop3: 0.0,
89
- prop4: undefined,
90
- prop5: null,
91
- prop6: {},
92
- prop7: [],
93
- };
94
- // When
95
- const res = inspector.extractSchema(eventProperties);
96
- // Then
97
- expect(res[0].propertyType).toBe(constants_1.type.BOOL);
98
- expect(res[1].propertyType).toBe(constants_1.type.INT);
99
- expect(res[2].propertyType).toBe(constants_1.type.STRING);
100
- expect(res[3].propertyType).toBe(constants_1.type.INT);
101
- expect(res[4].propertyType).toBe(constants_1.type.NULL);
102
- expect(res[5].propertyType).toBe(constants_1.type.NULL);
103
- expect(res[6].propertyType).toBe(constants_1.type.OBJECT);
104
- expect(res[6].children).toMatchObject([]);
105
- expect(res[7].propertyType).toBe(constants_1.type.STRINGLIST);
106
- expect(res[7].children).toMatchObject([]);
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
- });
128
- });
@@ -1,42 +0,0 @@
1
- declare const defaultOptions: {
2
- apiKey: string;
3
- env: "dev";
4
- version: string;
5
- shouldLog: boolean;
6
- appName: string;
7
- };
8
- declare const error: {
9
- API_KEY: string;
10
- VERSION: string;
11
- };
12
- declare const mockedReturns: {
13
- INSTALLATION_ID: string;
14
- GUID: string;
15
- SESSION_ID: string;
16
- };
17
- declare const networkCallType: {
18
- EVENT: string;
19
- SESSION_STARTED: string;
20
- };
21
- declare const requestMsg: {
22
- ERROR: string;
23
- TIMEOUT: string;
24
- };
25
- declare const trackingEndpoint = "https://api.avo.app/inspector/v1/track";
26
- declare const sessionTimeMs: number;
27
- declare const type: {
28
- STRING: string;
29
- STRINGLIST: string;
30
- INT: string;
31
- INTLIST: string;
32
- OBJECT: string;
33
- OBJECTLIST: string;
34
- FLOAT: string;
35
- FLOATLIST: string;
36
- BOOL: string;
37
- BOOLLIST: string;
38
- NULL: string;
39
- UNKNOWN: string;
40
- UNKNOWNLIST: string;
41
- };
42
- export { defaultOptions, error, mockedReturns, networkCallType, requestMsg, sessionTimeMs, type, trackingEndpoint, };