avo-inspector 3.0.1 → 3.1.0-alpha.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.
- package/README.md +32 -0
- package/dist/AvoBatcher.js +79 -0
- package/dist/AvoDeduplicator.d.ts +12 -4
- package/{dist-native → dist}/AvoDeduplicator.js +45 -46
- package/dist/AvoEncryption.js +282 -0
- package/{dist-native → dist}/AvoGuid.js +2 -1
- package/dist/AvoInspector.js +474 -0
- package/{dist-native → dist}/AvoInspectorEnv.js +1 -1
- package/dist/AvoNetworkCallsHandler.js +185 -0
- package/dist/AvoSchemaParser.js +132 -0
- package/dist/AvoStorage.js +256 -0
- package/dist/AvoStreamId.js +144 -0
- package/{dist-browser → dist}/__mocks__/xhr.d.ts +0 -1
- package/{dist-browser → dist}/__mocks__/xhrError.d.ts +0 -1
- package/dist/__tests__/helpers/encryptionHelpers.d.ts +24 -0
- package/dist/__tests__/helpers/mockFactories.d.ts +68 -0
- package/dist/esm/AvoBatcher.js +75 -0
- package/dist/esm/AvoDeduplicator.js +137 -0
- package/dist/esm/AvoEncryption.js +277 -0
- package/dist/esm/AvoGuid.js +9 -0
- package/dist/esm/AvoInspector.js +470 -0
- package/dist/esm/AvoInspectorEnv.js +5 -0
- package/dist/esm/AvoNetworkCallsHandler.js +181 -0
- package/dist/esm/AvoSchemaParser.js +128 -0
- package/dist/esm/AvoStorage.js +176 -0
- package/dist/esm/AvoStreamId.js +140 -0
- package/dist/esm/eventSpec/AvoEventSpecCache.js +165 -0
- package/dist/esm/eventSpec/AvoEventSpecFetchTypes.js +6 -0
- package/dist/esm/eventSpec/AvoEventSpecFetcher.js +203 -0
- package/dist/esm/eventSpec/EventValidator.js +687 -0
- package/{dist-native/index.d.ts → dist/esm/index.js} +1 -0
- package/dist/esm/utils.js +38 -0
- package/dist/esm/version.js +2 -0
- package/dist/eventSpec/AvoEventSpecCache.d.ts +10 -2
- package/dist/eventSpec/AvoEventSpecCache.js +169 -0
- package/dist/eventSpec/AvoEventSpecFetchTypes.d.ts +2 -2
- package/dist/eventSpec/AvoEventSpecFetchTypes.js +7 -0
- package/dist/eventSpec/AvoEventSpecFetcher.js +207 -0
- package/dist/eventSpec/EventValidator.js +690 -0
- package/dist/eventSpec/index.js +20 -0
- package/dist/index.js +1 -1
- package/dist/lite/AvoBatcherLite.d.ts +17 -0
- package/{dist-native/AvoBatcher.js → dist/lite/AvoBatcherLite.js} +16 -11
- package/{dist-native/AvoInspector.d.ts → dist/lite/AvoInspectorLite.d.ts} +17 -20
- package/dist/lite/AvoInspectorLite.js +247 -0
- package/{dist-browser/AvoNetworkCallsHandler.d.ts → dist/lite/AvoNetworkCallsHandlerLite.d.ts} +31 -23
- package/dist/lite/AvoNetworkCallsHandlerLite.js +164 -0
- package/dist/lite/AvoSchemaParserLite.d.ts +7 -0
- package/dist/lite/AvoSchemaParserLite.js +170 -0
- package/dist/lite/index.d.ts +2 -0
- package/{dist-native → dist/lite}/index.js +3 -3
- package/{dist-native → dist}/utils.js +2 -2
- package/dist/version.d.ts +1 -0
- package/dist/version.js +5 -0
- package/package.json +30 -6
- package/{lib/ocaml/AvoInspector.res → rescript/AvoInspectorLite.res} +3 -4
- package/{lib/ocaml/AvoInspector.resi → rescript/AvoInspectorLite.resi} +2 -2
- package/rescript.json +16 -0
- package/.eslintrc.json +0 -24
- package/CHANGELOG.md +0 -95
- package/dist/AvoAnonymousId.d.ts +0 -26
- package/dist/AvoInstallationId.d.ts +0 -5
- package/dist/AvoSessionTracker.d.ts +0 -15
- package/dist/browser.js.LICENSE.txt +0 -5
- package/dist/eventSpec/AvoGuid.d.ts +0 -3
- package/dist/eventSpec/cache.d.ts +0 -73
- package/dist/eventSpec/types.d.ts +0 -74
- package/dist/index.js.LICENSE.txt +0 -3
- package/dist-browser/AvoAnonymousId.d.ts +0 -26
- package/dist-browser/AvoBatcher.d.ts +0 -26
- package/dist-browser/AvoDeduplicator.d.ts +0 -20
- package/dist-browser/AvoEncryption.d.ts +0 -33
- package/dist-browser/AvoGuid.d.ts +0 -3
- package/dist-browser/AvoInspector.d.ts +0 -78
- package/dist-browser/AvoInspectorEnv.d.ts +0 -7
- package/dist-browser/AvoSchemaParser.d.ts +0 -20
- package/dist-browser/AvoStorage.d.ts +0 -22
- package/dist-browser/__tests__/helpers/encryptionHelpers.d.ts +0 -13
- package/dist-browser/__tests__/helpers/mockFactories.d.ts +0 -49
- package/dist-browser/eventSpec/AvoEventSpecCache.d.ts +0 -73
- package/dist-browser/eventSpec/AvoEventSpecFetchTypes.d.ts +0 -109
- package/dist-browser/eventSpec/AvoEventSpecFetcher.d.ts +0 -55
- package/dist-browser/eventSpec/EventValidator.d.ts +0 -90
- package/dist-browser/index.d.ts +0 -2
- package/dist-browser/utils.d.ts +0 -3
- package/dist-native/AvoBatcher.d.ts +0 -24
- package/dist-native/AvoDeduplicator.d.ts +0 -36
- package/dist-native/AvoGuid.d.ts +0 -3
- package/dist-native/AvoInspector.js +0 -220
- package/dist-native/AvoInspectorEnv.d.ts +0 -7
- package/dist-native/AvoInstallationId.d.ts +0 -5
- package/dist-native/AvoInstallationId.js +0 -36
- package/dist-native/AvoNetworkCallsHandler.d.ts +0 -48
- package/dist-native/AvoNetworkCallsHandler.js +0 -142
- package/dist-native/AvoSchemaParser.d.ts +0 -11
- package/dist-native/AvoSchemaParser.js +0 -95
- package/dist-native/AvoSessionTracker.d.ts +0 -15
- package/dist-native/AvoSessionTracker.js +0 -104
- package/dist-native/AvoStorage.d.ts +0 -22
- package/dist-native/AvoStorage.js +0 -336
- package/dist-native/__mocks__/xhr.d.ts +0 -12
- package/dist-native/__mocks__/xhr.js +0 -14
- package/dist-native/__mocks__/xhrError.d.ts +0 -12
- package/dist-native/__mocks__/xhrError.js +0 -14
- package/dist-native/__tests__/AvoInspector.js +0 -207
- package/dist-native/__tests__/Batcher.js +0 -280
- package/dist-native/__tests__/BatcherPublic.d.ts +0 -1
- package/dist-native/__tests__/BatcherPublic.js +0 -82
- package/dist-native/__tests__/Deduplicator.d.ts +0 -1
- package/dist-native/__tests__/Deduplicator.js +0 -111
- package/dist-native/__tests__/InstallationId.d.ts +0 -1
- package/dist-native/__tests__/InstallationId.js +0 -40
- package/dist-native/__tests__/NetworkCallsHandler.d.ts +0 -1
- package/dist-native/__tests__/NetworkCallsHandler.js +0 -132
- package/dist-native/__tests__/Parsing.d.ts +0 -1
- package/dist-native/__tests__/Parsing.js +0 -115
- package/dist-native/__tests__/Sessions.d.ts +0 -1
- package/dist-native/__tests__/Sessions.js +0 -179
- package/dist-native/__tests__/Storage.d.ts +0 -1
- package/dist-native/__tests__/Storage.js +0 -173
- package/dist-native/__tests__/constants.d.ts +0 -36
- package/dist-native/__tests__/constants.js +0 -47
- package/dist-native/utils.d.ts +0 -3
- package/jest.config.js +0 -33
- package/lib/bs/.bsbuild +0 -5
- package/lib/bs/.bsdeps +0 -8
- package/lib/bs/.compiler.log +0 -2
- package/lib/bs/.ninja_log +0 -7
- package/lib/bs/build.ninja +0 -19
- package/lib/bs/install.ninja +0 -12
- package/lib/bs/rescript/AvoInspector.ast +0 -0
- package/lib/bs/rescript/AvoInspector.cmi +0 -0
- package/lib/bs/rescript/AvoInspector.cmj +0 -0
- package/lib/bs/rescript/AvoInspector.cmt +0 -0
- package/lib/bs/rescript/AvoInspector.cmti +0 -0
- package/lib/bs/rescript/AvoInspector.d +0 -0
- package/lib/bs/rescript/AvoInspector.iast +0 -0
- package/lib/ocaml/.compiler.log +0 -2
- package/lib/ocaml/.ninja_log +0 -8
- package/lib/ocaml/AvoInspector.cmi +0 -0
- package/lib/ocaml/AvoInspector.cmj +0 -0
- package/lib/ocaml/AvoInspector.cmt +0 -0
- package/lib/ocaml/AvoInspector.cmti +0 -0
- package/lib/ocaml/install.stamp +0 -0
- package/rescript/AvoInspector.mjs +0 -11
- package/webpack.browserConfig.js +0 -26
- package/webpack.config.js +0 -26
- /package/{dist-browser → dist}/__tests__/AvoEncryption_test.d.ts +0 -0
- /package/{dist-browser → dist}/__tests__/AvoInspectorEventSpec_test.d.ts +0 -0
- /package/{dist-browser/__tests__/AnonymousId_test.d.ts → dist/__tests__/AvoInspectorLite_test.d.ts} +0 -0
- /package/{dist-browser → dist}/__tests__/AvoInspector_test.d.ts +0 -0
- /package/{dist-browser/__tests__/BatcherPublic_test.d.ts → dist/__tests__/AvoSchemaParserLite_test.d.ts} +0 -0
- /package/{dist-browser/__tests__/Batcher_test.d.ts → dist/__tests__/BatcherPublic_test.d.ts} +0 -0
- /package/{dist-browser/__tests__/Deduplicator_test.d.ts → dist/__tests__/Batcher_test.d.ts} +0 -0
- /package/{dist-browser/__tests__/EncryptedPropertyTracking_test.d.ts → dist/__tests__/Deduplicator_test.d.ts} +0 -0
- /package/{dist-browser/__tests__/EventSpecCache_test.d.ts → dist/__tests__/EncryptedPropertyTracking_test.d.ts} +0 -0
- /package/{dist-browser/__tests__/EventSpecFetcher_test.d.ts → dist/__tests__/EventSpecCache_test.d.ts} +0 -0
- /package/{dist-browser/__tests__/EventValidator_test.d.ts → dist/__tests__/EventSpecFetcher_test.d.ts} +0 -0
- /package/{dist-browser/__tests__/NetworkCallsHandler_test.d.ts → dist/__tests__/EventValidator_test.d.ts} +0 -0
- /package/{dist-browser/__tests__/Parsing_test.d.ts → dist/__tests__/NetworkCallsHandler_test.d.ts} +0 -0
- /package/{dist-browser/__tests__/Storage_test.d.ts → dist/__tests__/Parsing_test.d.ts} +0 -0
- /package/{dist-browser/__tests__/ValidationIntegration_test.d.ts → dist/__tests__/Storage_test.d.ts} +0 -0
- /package/{dist-native/__tests__/AvoInspector.d.ts → dist/__tests__/StreamId_test.d.ts} +0 -0
- /package/{dist-native/__tests__/Batcher.d.ts → dist/__tests__/ValidationIntegration_test.d.ts} +0 -0
- /package/{dist-browser → dist}/__tests__/constants.d.ts +0 -0
- /package/{dist-browser/eventSpec/index.d.ts → dist/esm/eventSpec/index.js} +0 -0
package/README.md
CHANGED
|
@@ -25,6 +25,38 @@ or
|
|
|
25
25
|
yarn add avo-inspector
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
# Lite Build (Production-Optimized)
|
|
29
|
+
|
|
30
|
+
For size-sensitive deployments (GTM, script tags, etc.), use the lite entry point which excludes encryption and event spec validation — reducing the gzipped bundle from ~37 KB to ~7.5 KB:
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
import { AvoInspector, AvoInspectorEnv } from "avo-inspector/lite";
|
|
34
|
+
|
|
35
|
+
let inspector = new AvoInspector({
|
|
36
|
+
apiKey: "your api key",
|
|
37
|
+
env: AvoInspectorEnv.Prod,
|
|
38
|
+
version: "1.0.0",
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The lite build has the same tracking API as the full version — `trackSchemaFromEvent`, `trackSchema`, and `extractSchema` all work identically. The differences:
|
|
43
|
+
|
|
44
|
+
- No `publicEncryptionKey` constructor option (TypeScript will error if passed)
|
|
45
|
+
- No event spec validation (dev/staging feature)
|
|
46
|
+
- No property value encryption (dev/staging feature)
|
|
47
|
+
- No stream ID generation/persistence (dev/staging debugger feature)
|
|
48
|
+
- No event deduplication — **if you use both Avo Codegen and manual `trackSchemaFromEvent` calls for the same events, use the full build instead** to avoid sending duplicate schemas
|
|
49
|
+
- Works universally with any bundler or minifier — no flags or configuration needed
|
|
50
|
+
|
|
51
|
+
**Size comparison:**
|
|
52
|
+
|
|
53
|
+
| | Minified | Gzipped |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| Full (`avo-inspector`) | 129 KB | 37 KB |
|
|
56
|
+
| Lite (`avo-inspector/lite`) | 20 KB | 5.2 KB |
|
|
57
|
+
|
|
58
|
+
See `examples/lite-size-demos/` for working examples with terser, webpack, and rollup.
|
|
59
|
+
|
|
28
60
|
# Initialization
|
|
29
61
|
|
|
30
62
|
Obtain the API key at [Avo.app](https://www.avo.app/welcome)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AvoBatcher = void 0;
|
|
4
|
+
const AvoInspector_1 = require("./AvoInspector");
|
|
5
|
+
class AvoBatcher {
|
|
6
|
+
constructor(networkCallsHandler) {
|
|
7
|
+
this.events = [];
|
|
8
|
+
this.networkCallsHandler = networkCallsHandler;
|
|
9
|
+
this.batchFlushAttemptTimestamp = Date.now();
|
|
10
|
+
AvoInspector_1.AvoInspector.avoStorage
|
|
11
|
+
.getItemAsync(AvoBatcher.cacheKey)
|
|
12
|
+
.then((savedEvents) => {
|
|
13
|
+
if (savedEvents !== null) {
|
|
14
|
+
const nonNullSavedEvents = savedEvents.filter((event) => event !== null);
|
|
15
|
+
this.events = this.events.concat(nonNullSavedEvents);
|
|
16
|
+
this.checkIfBatchNeedsToBeSent();
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
.catch((error) => {
|
|
20
|
+
console.error("Avo Inspector: error getting events from cache", error);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
handleSessionStarted() {
|
|
24
|
+
this.events.push(this.networkCallsHandler.bodyForSessionStartedCall());
|
|
25
|
+
this.saveEvents();
|
|
26
|
+
this.checkIfBatchNeedsToBeSent();
|
|
27
|
+
}
|
|
28
|
+
handleTrackSchema(eventName, schema, eventId, eventHash, eventSpecMetadata) {
|
|
29
|
+
this.events.push(this.networkCallsHandler.bodyForEventSchemaCall(eventName, schema, eventId, eventHash, eventSpecMetadata));
|
|
30
|
+
this.saveEvents();
|
|
31
|
+
if (AvoInspector_1.AvoInspector.shouldLog) {
|
|
32
|
+
console.log("Avo Inspector: saved event " +
|
|
33
|
+
eventName +
|
|
34
|
+
" with schema " +
|
|
35
|
+
JSON.stringify(schema));
|
|
36
|
+
}
|
|
37
|
+
this.checkIfBatchNeedsToBeSent();
|
|
38
|
+
}
|
|
39
|
+
checkIfBatchNeedsToBeSent() {
|
|
40
|
+
const batchSize = this.events.length;
|
|
41
|
+
const now = Date.now();
|
|
42
|
+
const timeSinceLastFlushAttempt = now - this.batchFlushAttemptTimestamp;
|
|
43
|
+
const sendBySize = batchSize % AvoInspector_1.AvoInspector.batchSize == 0;
|
|
44
|
+
const sendByTime = timeSinceLastFlushAttempt >= AvoInspector_1.AvoInspector.batchFlushSeconds * 1000;
|
|
45
|
+
const avoBatcher = this;
|
|
46
|
+
if (sendBySize || sendByTime) {
|
|
47
|
+
this.batchFlushAttemptTimestamp = now;
|
|
48
|
+
const sendingEvents = avoBatcher.events;
|
|
49
|
+
avoBatcher.events = [];
|
|
50
|
+
this.networkCallsHandler.callInspectorWithBatchBody(sendingEvents, function (error) {
|
|
51
|
+
if (error != null) {
|
|
52
|
+
avoBatcher.events = avoBatcher.events.concat(sendingEvents);
|
|
53
|
+
if (AvoInspector_1.AvoInspector.shouldLog) {
|
|
54
|
+
console.log("Avo Inspector: batch sending failed: " +
|
|
55
|
+
error.message +
|
|
56
|
+
". We will attempt to send your schemas with next batch");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
if (AvoInspector_1.AvoInspector.shouldLog) {
|
|
61
|
+
console.log("Avo Inspector: batch sent successfully.");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
avoBatcher.saveEvents();
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
saveEvents() {
|
|
69
|
+
if (this.events.length > 1000) {
|
|
70
|
+
const extraElements = this.events.length - 1000;
|
|
71
|
+
this.events.splice(0, extraElements);
|
|
72
|
+
}
|
|
73
|
+
AvoInspector_1.AvoInspector.avoStorage.setItem(AvoBatcher.cacheKey, this.events);
|
|
74
|
+
}
|
|
75
|
+
static get cacheKey() {
|
|
76
|
+
return "AvoInspectorEvents";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.AvoBatcher = AvoBatcher;
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
export declare class AvoDeduplicator {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
private _nextId;
|
|
3
|
+
avoFunctionsEvents: Record<string, string>;
|
|
4
|
+
manualEvents: Record<string, string>;
|
|
5
|
+
avoFunctionsEventsParams: Record<string, {
|
|
6
|
+
eventName: string;
|
|
7
|
+
params: Record<string, any>;
|
|
8
|
+
}>;
|
|
9
|
+
manualEventsParams: Record<string, {
|
|
10
|
+
eventName: string;
|
|
11
|
+
params: Record<string, any>;
|
|
12
|
+
}>;
|
|
6
13
|
shouldRegisterEvent(eventName: string, params: Record<string, any>, fromAvoFunction: boolean): boolean;
|
|
7
14
|
private hasSameEventAs;
|
|
15
|
+
private removeEntriesByName;
|
|
8
16
|
private lookForEventIn;
|
|
9
17
|
hasSeenEventParams(params: Record<string, any>, checkInAvoFunctions: boolean): boolean;
|
|
10
18
|
private lookForEventParamsIn;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AvoDeduplicator = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
const AvoSchemaParser_1 = require("./AvoSchemaParser");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
class AvoDeduplicator {
|
|
7
|
+
constructor() {
|
|
8
8
|
this.avoFunctionsEvents = {};
|
|
9
9
|
this.manualEvents = {};
|
|
10
10
|
this.avoFunctionsEventsParams = {};
|
|
11
11
|
this.manualEventsParams = {};
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
shouldRegisterEvent(eventName, params, fromAvoFunction) {
|
|
14
14
|
this.clearOldEvents();
|
|
15
15
|
if (fromAvoFunction) {
|
|
16
16
|
this.avoFunctionsEvents[Date.now()] = eventName;
|
|
@@ -20,11 +20,11 @@ var AvoDeduplicator = /** @class */ (function () {
|
|
|
20
20
|
this.manualEvents[Date.now()] = eventName;
|
|
21
21
|
this.manualEventsParams[eventName] = params;
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
const checkInAvoFunctions = !fromAvoFunction;
|
|
24
24
|
return !this.hasSameEventAs(eventName, params, checkInAvoFunctions);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
}
|
|
26
|
+
hasSameEventAs(eventName, params, checkInAvoFunctions) {
|
|
27
|
+
let result = false;
|
|
28
28
|
if (checkInAvoFunctions) {
|
|
29
29
|
if (this.lookForEventIn(eventName, params, this.avoFunctionsEventsParams)) {
|
|
30
30
|
result = true;
|
|
@@ -40,12 +40,12 @@ var AvoDeduplicator = /** @class */ (function () {
|
|
|
40
40
|
delete this.manualEventsParams[eventName];
|
|
41
41
|
}
|
|
42
42
|
return result;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
for (
|
|
43
|
+
}
|
|
44
|
+
lookForEventIn(eventName, params, eventsStorage) {
|
|
45
|
+
for (const otherEventName in eventsStorage) {
|
|
46
46
|
if (eventsStorage.hasOwnProperty(otherEventName)) {
|
|
47
47
|
if (otherEventName === eventName) {
|
|
48
|
-
|
|
48
|
+
const otherParams = eventsStorage[eventName];
|
|
49
49
|
if (otherParams && (0, utils_1.deepEquals)(params, otherParams)) {
|
|
50
50
|
return true;
|
|
51
51
|
}
|
|
@@ -53,9 +53,9 @@ var AvoDeduplicator = /** @class */ (function () {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
return false;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
}
|
|
57
|
+
hasSeenEventParams(params, checkInAvoFunctions) {
|
|
58
|
+
let result = false;
|
|
59
59
|
if (checkInAvoFunctions) {
|
|
60
60
|
if (this.lookForEventParamsIn(params, this.avoFunctionsEventsParams)) {
|
|
61
61
|
result = true;
|
|
@@ -67,37 +67,37 @@ var AvoDeduplicator = /** @class */ (function () {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
return result;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
for (
|
|
70
|
+
}
|
|
71
|
+
lookForEventParamsIn(params, eventsStorage) {
|
|
72
|
+
for (const otherEventName in eventsStorage) {
|
|
73
73
|
if (eventsStorage.hasOwnProperty(otherEventName)) {
|
|
74
|
-
|
|
74
|
+
const otherParams = eventsStorage[otherEventName];
|
|
75
75
|
if (otherParams && (0, utils_1.deepEquals)(params, otherParams)) {
|
|
76
76
|
return true;
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
return false;
|
|
81
|
-
}
|
|
82
|
-
|
|
81
|
+
}
|
|
82
|
+
async shouldRegisterSchemaFromManually(eventName, eventSchema) {
|
|
83
83
|
this.clearOldEvents();
|
|
84
|
-
return !this.hasSameShapeInAvoFunctionsAs(eventName, eventSchema);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (this.lookForEventSchemaIn(eventName, eventSchema, this.avoFunctionsEventsParams)) {
|
|
84
|
+
return !(await this.hasSameShapeInAvoFunctionsAs(eventName, eventSchema));
|
|
85
|
+
}
|
|
86
|
+
async hasSameShapeInAvoFunctionsAs(eventName, eventSchema) {
|
|
87
|
+
let result = false;
|
|
88
|
+
if (await this.lookForEventSchemaIn(eventName, eventSchema, this.avoFunctionsEventsParams)) {
|
|
89
89
|
result = true;
|
|
90
90
|
}
|
|
91
91
|
if (result) {
|
|
92
92
|
delete this.avoFunctionsEventsParams[eventName];
|
|
93
93
|
}
|
|
94
94
|
return result;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
for (
|
|
95
|
+
}
|
|
96
|
+
async lookForEventSchemaIn(eventName, eventSchema, eventsStorage) {
|
|
97
|
+
for (const otherEventName in eventsStorage) {
|
|
98
98
|
if (eventsStorage.hasOwnProperty(otherEventName)) {
|
|
99
99
|
if (otherEventName === eventName) {
|
|
100
|
-
|
|
100
|
+
const otherSchema = await AvoSchemaParser_1.AvoSchemaParser.extractSchema(eventsStorage[eventName]);
|
|
101
101
|
if (otherSchema && (0, utils_1.deepEquals)(eventSchema, otherSchema)) {
|
|
102
102
|
return true;
|
|
103
103
|
}
|
|
@@ -105,38 +105,37 @@ var AvoDeduplicator = /** @class */ (function () {
|
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
return false;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
for (
|
|
108
|
+
}
|
|
109
|
+
clearOldEvents() {
|
|
110
|
+
const now = Date.now();
|
|
111
|
+
const msToConsiderOld = 300;
|
|
112
|
+
for (const time in this.avoFunctionsEvents) {
|
|
113
113
|
if (this.avoFunctionsEvents.hasOwnProperty(time)) {
|
|
114
|
-
|
|
114
|
+
const timestamp = Number(time) || 0;
|
|
115
115
|
if (now - timestamp > msToConsiderOld) {
|
|
116
|
-
|
|
116
|
+
const eventName = this.avoFunctionsEvents[time];
|
|
117
117
|
delete this.avoFunctionsEvents[time];
|
|
118
118
|
delete this.avoFunctionsEventsParams[eventName];
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
|
-
for (
|
|
122
|
+
for (const time in this.manualEvents) {
|
|
123
123
|
if (this.manualEvents.hasOwnProperty(time)) {
|
|
124
|
-
|
|
124
|
+
const timestamp = Number(time) || 0;
|
|
125
125
|
if (now - timestamp > msToConsiderOld) {
|
|
126
|
-
|
|
126
|
+
const eventName = this.manualEvents[time];
|
|
127
127
|
delete this.manualEvents[time];
|
|
128
128
|
delete this.manualEventsParams[eventName];
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
}
|
|
132
|
+
}
|
|
133
133
|
// used in tests
|
|
134
|
-
|
|
134
|
+
_clearEvents() {
|
|
135
135
|
this.avoFunctionsEvents = {};
|
|
136
136
|
this.manualEvents = {};
|
|
137
137
|
this.avoFunctionsEventsParams = {};
|
|
138
138
|
this.manualEventsParams = {};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
}());
|
|
139
|
+
}
|
|
140
|
+
}
|
|
142
141
|
exports.AvoDeduplicator = AvoDeduplicator;
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateKeyPair = generateKeyPair;
|
|
4
|
+
exports.encryptValue = encryptValue;
|
|
5
|
+
exports.decryptValue = decryptValue;
|
|
6
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
|
+
const p256_1 = require("@noble/curves/p256");
|
|
8
|
+
/**
|
|
9
|
+
* Converts bytes (Uint8Array) to hex string
|
|
10
|
+
*/
|
|
11
|
+
function bytesToHex(bytes) {
|
|
12
|
+
return Array.from(bytes)
|
|
13
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
14
|
+
.join('');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Converts hex string to bytes (Uint8Array)
|
|
18
|
+
*/
|
|
19
|
+
function hexToBytes(hex) {
|
|
20
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
21
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
22
|
+
bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
|
|
23
|
+
}
|
|
24
|
+
return bytes;
|
|
25
|
+
}
|
|
26
|
+
// Get crypto API - works in both browser and Node.js environments
|
|
27
|
+
// In browser: window.crypto or globalThis.crypto
|
|
28
|
+
// In Node.js: global.crypto or globalThis.crypto (polyfilled in tests)
|
|
29
|
+
const getCrypto = () => {
|
|
30
|
+
// Try globalThis first (works in both Node.js and browsers)
|
|
31
|
+
if (typeof globalThis !== 'undefined' && globalThis.crypto) {
|
|
32
|
+
const crypto = globalThis.crypto;
|
|
33
|
+
if (crypto && crypto.subtle) {
|
|
34
|
+
return crypto;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Try window (browser)
|
|
38
|
+
if (typeof window !== 'undefined' && window.crypto) {
|
|
39
|
+
const crypto = window.crypto;
|
|
40
|
+
if (crypto && crypto.subtle) {
|
|
41
|
+
return crypto;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Try global (Node.js)
|
|
45
|
+
if (typeof global !== 'undefined' && global.crypto) {
|
|
46
|
+
const crypto = global.crypto;
|
|
47
|
+
if (crypto && crypto.subtle) {
|
|
48
|
+
return crypto;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Fallback - should not happen in proper environments
|
|
52
|
+
const debugInfo = {
|
|
53
|
+
hasGlobalThis: typeof globalThis !== 'undefined',
|
|
54
|
+
hasGlobalThisCrypto: typeof globalThis !== 'undefined' && !!globalThis.crypto,
|
|
55
|
+
hasGlobalThisCryptoSubtle: typeof globalThis !== 'undefined' && !!globalThis.crypto && !!globalThis.crypto.subtle,
|
|
56
|
+
hasWindow: typeof window !== 'undefined',
|
|
57
|
+
hasWindowCrypto: typeof window !== 'undefined' && !!window.crypto,
|
|
58
|
+
hasGlobal: typeof global !== 'undefined',
|
|
59
|
+
hasGlobalCrypto: typeof global !== 'undefined' && !!global.crypto,
|
|
60
|
+
hasGlobalCryptoSubtle: typeof global !== 'undefined' && !!global.crypto && !!global.crypto.subtle
|
|
61
|
+
};
|
|
62
|
+
throw new Error('crypto.subtle not available. Debug: ' + JSON.stringify(debugInfo));
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Generates a new ECC key pair for encryption/decryption.
|
|
66
|
+
* Uses P-256 (prime256v1 / NIST P-256) curve which is standard for Web Crypto API.
|
|
67
|
+
*
|
|
68
|
+
* @returns An object containing the private and public keys as hex strings
|
|
69
|
+
*/
|
|
70
|
+
function generateKeyPair() {
|
|
71
|
+
// Generate a new random private key (32 bytes)
|
|
72
|
+
const privateKeyBytes = p256_1.p256.utils.randomPrivateKey();
|
|
73
|
+
// Get public key (uncompressed format: 65 bytes = 0x04 + 32-byte x + 32-byte y)
|
|
74
|
+
const publicKeyBytes = p256_1.p256.getPublicKey(privateKeyBytes, false);
|
|
75
|
+
// Convert to hex strings
|
|
76
|
+
const privateKey = bytesToHex(privateKeyBytes).padStart(64, '0');
|
|
77
|
+
const publicKey = bytesToHex(publicKeyBytes);
|
|
78
|
+
return {
|
|
79
|
+
privateKey,
|
|
80
|
+
publicKey
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Derives a key from shared secret using SHA-256
|
|
85
|
+
*/
|
|
86
|
+
async function deriveKey(sharedSecret) {
|
|
87
|
+
const cryptoAPI = getCrypto();
|
|
88
|
+
return await cryptoAPI.subtle.digest('SHA-256', sharedSecret);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Safely converts Uint8Array to base64 string.
|
|
92
|
+
* Uses Buffer in Node.js for efficiency, or chunked conversion in browsers
|
|
93
|
+
* to avoid call stack overflow with large arrays.
|
|
94
|
+
*/
|
|
95
|
+
function uint8ArrayToBase64(bytes) {
|
|
96
|
+
// Check if we're in Node.js and Buffer is available
|
|
97
|
+
if (typeof Buffer !== 'undefined' && Buffer.from) {
|
|
98
|
+
return Buffer.from(bytes).toString('base64');
|
|
99
|
+
}
|
|
100
|
+
// Browser fallback: use chunked conversion to avoid call stack overflow
|
|
101
|
+
// Chunk size of 8192 (8k) is safe for String.fromCharCode.apply
|
|
102
|
+
const CHUNK_SIZE = 8192;
|
|
103
|
+
let binaryString = '';
|
|
104
|
+
for (let i = 0; i < bytes.length; i += CHUNK_SIZE) {
|
|
105
|
+
const chunk = bytes.slice(i, i + CHUNK_SIZE);
|
|
106
|
+
// Convert chunk to array and use apply for this small chunk
|
|
107
|
+
binaryString += String.fromCharCode.apply(null, Array.from(chunk));
|
|
108
|
+
}
|
|
109
|
+
return btoa(binaryString);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Encrypts a value using ECC public key encryption (ECIES).
|
|
113
|
+
* The encrypted output can only be decrypted by the client using their private key.
|
|
114
|
+
* This ensures that Avo cannot decrypt the values on the backend.
|
|
115
|
+
*
|
|
116
|
+
* ECIES uses hybrid encryption (ECDH + AES-256-GCM) which provides:
|
|
117
|
+
* - No message size limitations
|
|
118
|
+
* - Fast encryption even for large values
|
|
119
|
+
* - Strong authentication via GCM
|
|
120
|
+
*
|
|
121
|
+
* SPECIFICATION (Standard Web Crypto Profile):
|
|
122
|
+
* 1. Curve: P-256 (prime256v1 / NIST P-256)
|
|
123
|
+
* 2. Key Derivation (KDF): SHA-256(SharedSecret)
|
|
124
|
+
* 3. Cipher: AES-256-GCM
|
|
125
|
+
* 4. Serialization: [Version(1b)] + [EphemeralPubKey(33 or 65b)] + [IV(16b)] + [AuthTag(16b)] + [Ciphertext]
|
|
126
|
+
* Version 0x00 = Standard Web Profile
|
|
127
|
+
* EphemeralPubKey: 0x04 (uncompressed) + 64 bytes = 65 bytes total, or compressed format (33 bytes)
|
|
128
|
+
*
|
|
129
|
+
* @param value - The value to encrypt (any type - will be JSON stringified)
|
|
130
|
+
* @param publicKey - The ECC public key in hex format provided by the client
|
|
131
|
+
* @returns Promise resolving to base64-encoded encrypted string that can only be decrypted with the private key
|
|
132
|
+
*/
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
134
|
+
async function encryptValue(value, publicKey) {
|
|
135
|
+
try {
|
|
136
|
+
// Convert the value to a JSON string to support all types
|
|
137
|
+
// Note: JSON.stringify(undefined) returns undefined (not a string), so handle it explicitly
|
|
138
|
+
const stringValue = value === undefined ? 'null' : JSON.stringify(value);
|
|
139
|
+
if (stringValue === undefined) {
|
|
140
|
+
throw new Error('Cannot encrypt undefined value');
|
|
141
|
+
}
|
|
142
|
+
// 1. Prepare Public Key
|
|
143
|
+
// Ensure publicKey is a string
|
|
144
|
+
const publicKeyStr = typeof publicKey === 'string' ? publicKey : String(publicKey);
|
|
145
|
+
// Convert recipient's public key from hex to bytes
|
|
146
|
+
const recipientPublicKeyBytes = hexToBytes(publicKeyStr);
|
|
147
|
+
// 2. Generate Ephemeral Key Pair on P-256
|
|
148
|
+
const ephemeralPrivateKeyBytes = p256_1.p256.utils.randomPrivateKey();
|
|
149
|
+
const ephemeralPublicKeyBytes = p256_1.p256.getPublicKey(ephemeralPrivateKeyBytes, false); // Uncompressed format (65 bytes)
|
|
150
|
+
// 3. Derive Shared Secret (ECDH)
|
|
151
|
+
// getSharedSecret returns compressed point (33 bytes: 0x02/0x03 + X-coordinate)
|
|
152
|
+
// Extract X-coordinate (last 32 bytes) to match elliptic's derive().toArray("be", 32)
|
|
153
|
+
const sharedSecretPoint = p256_1.p256.getSharedSecret(ephemeralPrivateKeyBytes, recipientPublicKeyBytes);
|
|
154
|
+
const sharedSecret = sharedSecretPoint.slice(-32); // Extract X-coordinate (last 32 bytes)
|
|
155
|
+
// 4. Key Derivation (Hash with SHA-256)
|
|
156
|
+
const derivedKeyBuffer = await deriveKey(sharedSecret);
|
|
157
|
+
// 5. Import Key for Web Crypto AES-GCM
|
|
158
|
+
const cryptoAPI = getCrypto();
|
|
159
|
+
const keyMaterial = await cryptoAPI.subtle.importKey('raw', derivedKeyBuffer, { name: 'AES-GCM' }, false, ['encrypt']);
|
|
160
|
+
// 6. Generate random IV (16 bytes)
|
|
161
|
+
const iv = cryptoAPI.getRandomValues(new Uint8Array(16));
|
|
162
|
+
// 7. Encrypt using AES-256-GCM
|
|
163
|
+
// Convert string to Uint8Array
|
|
164
|
+
const plaintext = new TextEncoder().encode(stringValue);
|
|
165
|
+
const encryptedData = await cryptoAPI.subtle.encrypt({
|
|
166
|
+
name: 'AES-GCM',
|
|
167
|
+
iv,
|
|
168
|
+
tagLength: 128 // 16 bytes = 128 bits
|
|
169
|
+
}, keyMaterial, plaintext);
|
|
170
|
+
// Web Crypto API appends the auth tag to the ciphertext
|
|
171
|
+
// We need to extract it separately for our format
|
|
172
|
+
const encryptedArray = new Uint8Array(encryptedData);
|
|
173
|
+
const authTagLength = 16; // 128 bits = 16 bytes
|
|
174
|
+
const ciphertextLength = encryptedArray.length - authTagLength;
|
|
175
|
+
const ciphertext = encryptedArray.slice(0, ciphertextLength);
|
|
176
|
+
const authTag = encryptedArray.slice(ciphertextLength);
|
|
177
|
+
// 8. Serialize Output
|
|
178
|
+
// Format: [Version(1)] + [Ephemeral Public Key(65)] + [IV(16)] + [AuthTag(16)] + [Ciphertext]
|
|
179
|
+
const version = new Uint8Array([0x00]); // Version 0: Standard Web Profile
|
|
180
|
+
// Combine all parts
|
|
181
|
+
const resultLength = 1 + ephemeralPublicKeyBytes.length + 16 + 16 + ciphertext.length;
|
|
182
|
+
const result = new Uint8Array(resultLength);
|
|
183
|
+
let offset = 0;
|
|
184
|
+
result.set(version, offset);
|
|
185
|
+
offset += 1;
|
|
186
|
+
result.set(ephemeralPublicKeyBytes, offset);
|
|
187
|
+
offset += ephemeralPublicKeyBytes.length;
|
|
188
|
+
result.set(iv, offset);
|
|
189
|
+
offset += 16;
|
|
190
|
+
result.set(authTag, offset);
|
|
191
|
+
offset += 16;
|
|
192
|
+
result.set(ciphertext, offset);
|
|
193
|
+
// Convert to base64 using safe conversion that handles large arrays
|
|
194
|
+
return uint8ArrayToBase64(result);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
throw new Error(`Failed to encrypt value. Please check that the public key is valid. Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Decrypts a value that was encrypted with encryptValue.
|
|
202
|
+
*
|
|
203
|
+
* SPECIFICATION (Standard Web Crypto Profile):
|
|
204
|
+
* 1. Curve: P-256 (prime256v1 / NIST P-256)
|
|
205
|
+
* 2. Key Derivation (KDF): SHA-256(SharedSecret)
|
|
206
|
+
* 3. Cipher: AES-256-GCM
|
|
207
|
+
* 4. Deserialization: [Version(1b)] + [EphemeralPubKey(33 or 65b)] + [IV(16b)] + [AuthTag(16b)] + [Ciphertext]
|
|
208
|
+
*
|
|
209
|
+
* @param encryptedValue - The base64-encoded encrypted string
|
|
210
|
+
* @param privateKey - The ECC private key in hex format
|
|
211
|
+
* @returns Promise resolving to the original decrypted value (parsed from JSON)
|
|
212
|
+
*/
|
|
213
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
214
|
+
async function decryptValue(encryptedValue, privateKey) {
|
|
215
|
+
try {
|
|
216
|
+
// Convert encrypted value from base64 to Uint8Array
|
|
217
|
+
const binaryString = atob(encryptedValue);
|
|
218
|
+
const encryptedBuffer = new Uint8Array(binaryString.length);
|
|
219
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
220
|
+
encryptedBuffer[i] = binaryString.charCodeAt(i);
|
|
221
|
+
}
|
|
222
|
+
// Minimum size: version(1) + pubkey(33 min) + iv(16) + authTag(16) + ciphertext(1 min) = 67 bytes
|
|
223
|
+
if (encryptedBuffer.length < 67) {
|
|
224
|
+
throw new Error('Invalid encrypted data: payload too short');
|
|
225
|
+
}
|
|
226
|
+
// Ensure privateKey is a string
|
|
227
|
+
const privateKeyStr = typeof privateKey === 'string' ? privateKey : String(privateKey);
|
|
228
|
+
// 1. Deserialize Input
|
|
229
|
+
// Format: [Version(1)] + [Ephemeral Public Key(33 or 65)] + [IV(16)] + [AuthTag(16)] + [Ciphertext]
|
|
230
|
+
let offset = 0;
|
|
231
|
+
const version = encryptedBuffer[offset];
|
|
232
|
+
offset += 1;
|
|
233
|
+
if (version !== 0x00) {
|
|
234
|
+
throw new Error(`Unsupported encryption version: ${version}`);
|
|
235
|
+
}
|
|
236
|
+
// Check header to determine public key size (0x02/0x03 = 33 bytes compressed, 0x04 = 65 bytes uncompressed)
|
|
237
|
+
const keyHeader = encryptedBuffer[offset];
|
|
238
|
+
const pubKeySize = keyHeader === 0x02 || keyHeader === 0x03 ? 33 : 65;
|
|
239
|
+
// Validate buffer has enough bytes for this key format
|
|
240
|
+
const minRequired = 1 + pubKeySize + 16 + 16 + 1;
|
|
241
|
+
if (encryptedBuffer.length < minRequired) {
|
|
242
|
+
throw new Error(`Invalid encrypted data: expected at least ${minRequired} bytes, got ${encryptedBuffer.length}`);
|
|
243
|
+
}
|
|
244
|
+
const ephemeralPublicKey = encryptedBuffer.slice(offset, offset + pubKeySize);
|
|
245
|
+
offset += pubKeySize;
|
|
246
|
+
const iv = encryptedBuffer.slice(offset, offset + 16); // IV (16 bytes)
|
|
247
|
+
offset += 16;
|
|
248
|
+
const authTag = encryptedBuffer.slice(offset, offset + 16); // Auth tag (16 bytes)
|
|
249
|
+
offset += 16;
|
|
250
|
+
const ciphertext = encryptedBuffer.slice(offset); // Remaining bytes are ciphertext
|
|
251
|
+
// 2. Prepare Private Key
|
|
252
|
+
const recipientPrivateKeyBytes = hexToBytes(privateKeyStr);
|
|
253
|
+
// 3. Derive Shared Secret (ECDH)
|
|
254
|
+
// getSharedSecret returns compressed point (33 bytes: 0x02/0x03 + X-coordinate)
|
|
255
|
+
// Extract X-coordinate (last 32 bytes) to match elliptic's derive().toArray("be", 32)
|
|
256
|
+
const sharedSecretPoint = p256_1.p256.getSharedSecret(recipientPrivateKeyBytes, ephemeralPublicKey);
|
|
257
|
+
const sharedSecret = sharedSecretPoint.slice(-32); // Extract X-coordinate (last 32 bytes)
|
|
258
|
+
// 4. Key Derivation (Hash with SHA-256)
|
|
259
|
+
const derivedKeyBuffer = await deriveKey(sharedSecret);
|
|
260
|
+
// 5. Import Key for Web Crypto AES-GCM
|
|
261
|
+
const cryptoAPI = getCrypto();
|
|
262
|
+
const keyMaterial = await cryptoAPI.subtle.importKey('raw', derivedKeyBuffer, { name: 'AES-GCM' }, false, ['decrypt']);
|
|
263
|
+
// 6. Decrypt using AES-256-GCM
|
|
264
|
+
// Web Crypto API expects the auth tag appended to ciphertext
|
|
265
|
+
const combinedLength = ciphertext.length + authTag.length;
|
|
266
|
+
const data = new Uint8Array(combinedLength);
|
|
267
|
+
data.set(ciphertext, 0);
|
|
268
|
+
data.set(authTag, ciphertext.length);
|
|
269
|
+
const decryptedBuffer = await cryptoAPI.subtle.decrypt({
|
|
270
|
+
name: 'AES-GCM',
|
|
271
|
+
iv,
|
|
272
|
+
tagLength: 128 // 16 bytes = 128 bits
|
|
273
|
+
}, keyMaterial, data);
|
|
274
|
+
// 7. Convert to string and parse JSON
|
|
275
|
+
const decoder = new TextDecoder();
|
|
276
|
+
const stringValue = decoder.decode(decryptedBuffer);
|
|
277
|
+
return JSON.parse(stringValue);
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
throw new Error(`Failed to decrypt value. Please check that the private key is valid and matches the public key used for encryption. Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
@@ -5,7 +5,8 @@ var AvoGuid = /** @class */ (function () {
|
|
|
5
5
|
}
|
|
6
6
|
AvoGuid.newGuid = function () {
|
|
7
7
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
|
8
|
-
var r = (Math.random() * 16) | 0
|
|
8
|
+
var r = (Math.random() * 16) | 0;
|
|
9
|
+
var v = c === "x" ? r : (r & 0x3) | 0x8;
|
|
9
10
|
return v.toString(16);
|
|
10
11
|
});
|
|
11
12
|
};
|