posthog-node 4.14.0 → 4.15.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/CHANGELOG.md +5 -0
- package/lib/index.cjs.js +224 -25
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +42 -0
- package/lib/index.esm.js +224 -25
- package/lib/index.esm.js.map +1 -1
- package/lib/posthog-core/src/index.d.ts +10 -0
- package/lib/posthog-core/src/utils.d.ts +1 -0
- package/lib/posthog-node/src/posthog-node.d.ts +7 -0
- package/lib/posthog-node/src/types.d.ts +26 -0
- package/package.json +1 -1
- package/src/posthog-node.ts +100 -0
- package/src/types.ts +26 -0
package/lib/index.d.ts
CHANGED
|
@@ -441,12 +441,19 @@ declare abstract class PostHogCoreStateless {
|
|
|
441
441
|
*** TRACKING
|
|
442
442
|
***/
|
|
443
443
|
protected identifyStateless(distinctId: string, properties?: PostHogEventProperties, options?: PostHogCaptureOptions): void;
|
|
444
|
+
protected identifyStatelessImmediate(distinctId: string, properties?: PostHogEventProperties, options?: PostHogCaptureOptions): Promise<void>;
|
|
444
445
|
protected captureStateless(distinctId: string, event: string, properties?: {
|
|
445
446
|
[key: string]: any;
|
|
446
447
|
}, options?: PostHogCaptureOptions): void;
|
|
448
|
+
protected captureStatelessImmediate(distinctId: string, event: string, properties?: {
|
|
449
|
+
[key: string]: any;
|
|
450
|
+
}, options?: PostHogCaptureOptions): Promise<void>;
|
|
447
451
|
protected aliasStateless(alias: string, distinctId: string, properties?: {
|
|
448
452
|
[key: string]: any;
|
|
449
453
|
}, options?: PostHogCaptureOptions): void;
|
|
454
|
+
protected aliasStatelessImmediate(alias: string, distinctId: string, properties?: {
|
|
455
|
+
[key: string]: any;
|
|
456
|
+
}, options?: PostHogCaptureOptions): Promise<void>;
|
|
450
457
|
/***
|
|
451
458
|
*** GROUPS
|
|
452
459
|
***/
|
|
@@ -495,6 +502,8 @@ declare abstract class PostHogCoreStateless {
|
|
|
495
502
|
*** QUEUEING AND FLUSHING
|
|
496
503
|
***/
|
|
497
504
|
protected enqueue(type: string, _message: any, options?: PostHogCaptureOptions): void;
|
|
505
|
+
protected sendImmediate(type: string, _message: any, options?: PostHogCaptureOptions): Promise<void>;
|
|
506
|
+
private prepareMessage;
|
|
498
507
|
private clearFlushTimer;
|
|
499
508
|
/**
|
|
500
509
|
* Helper for flushing the queue in the background
|
|
@@ -542,6 +551,15 @@ type PostHogNodeV1 = {
|
|
|
542
551
|
* @param sendFeatureFlags OPTIONAL | Used with experiments. Determines whether to send feature flag values with the event.
|
|
543
552
|
*/
|
|
544
553
|
capture({ distinctId, event, properties, groups, sendFeatureFlags }: EventMessage): void;
|
|
554
|
+
/**
|
|
555
|
+
* @description Capture an event immediately. Useful for edge environments where the usual queue-based sending is not preferable. Do not mix immediate and non-immediate calls.
|
|
556
|
+
* @param distinctId which uniquely identifies your user
|
|
557
|
+
* @param event We recommend using [verb] [noun], like movie played or movie updated to easily identify what your events mean later on.
|
|
558
|
+
* @param properties OPTIONAL | which can be a object with any information you'd like to add
|
|
559
|
+
* @param groups OPTIONAL | object of what groups are related to this event, example: { company: 'id:5' }. Can be used to analyze companies instead of users.
|
|
560
|
+
* @param sendFeatureFlags OPTIONAL | Used with experiments. Determines whether to send feature flag values with the event.
|
|
561
|
+
*/
|
|
562
|
+
captureImmediate({ distinctId, event, properties, groups, sendFeatureFlags }: EventMessage): Promise<void>;
|
|
545
563
|
/**
|
|
546
564
|
* @description Identify lets you add metadata on your users so you can more easily identify who they are in PostHog,
|
|
547
565
|
* and even do things like segment users by these properties.
|
|
@@ -550,6 +568,13 @@ type PostHogNodeV1 = {
|
|
|
550
568
|
* @param properties with a dict with any key: value pairs
|
|
551
569
|
*/
|
|
552
570
|
identify({ distinctId, properties }: IdentifyMessage): void;
|
|
571
|
+
/**
|
|
572
|
+
* @description Identify lets you add metadata on your users so you can more easily identify who they are in PostHog.
|
|
573
|
+
* Useful for edge environments where the usual queue-based sending is not preferable. Do not mix immediate and non-immediate calls.
|
|
574
|
+
* @param distinctId which uniquely identifies your user
|
|
575
|
+
* @param properties with a dict with any key: value pairs
|
|
576
|
+
*/
|
|
577
|
+
identifyImmediate({ distinctId, properties }: IdentifyMessage): Promise<void>;
|
|
553
578
|
/**
|
|
554
579
|
* @description To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call.
|
|
555
580
|
* This will allow you to answer questions like "Which marketing channels leads to users churning after a month?"
|
|
@@ -565,6 +590,16 @@ type PostHogNodeV1 = {
|
|
|
565
590
|
distinctId: string;
|
|
566
591
|
alias: string;
|
|
567
592
|
}): void;
|
|
593
|
+
/**
|
|
594
|
+
* @description To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call.
|
|
595
|
+
* Useful for edge environments where the usual queue-based sending is not preferable. Do not mix immediate and non-immediate calls.
|
|
596
|
+
* @param distinctId the current unique id
|
|
597
|
+
* @param alias the unique ID of the user before
|
|
598
|
+
*/
|
|
599
|
+
aliasImmediate(data: {
|
|
600
|
+
distinctId: string;
|
|
601
|
+
alias: string;
|
|
602
|
+
}): Promise<void>;
|
|
568
603
|
/**
|
|
569
604
|
* @description PostHog feature flags (https://posthog.com/docs/features/feature-flags)
|
|
570
605
|
* allow you to safely deploy and roll back new features. Once you've created a feature flag in PostHog,
|
|
@@ -726,12 +761,19 @@ declare class PostHog extends PostHogCoreStateless implements PostHogNodeV1 {
|
|
|
726
761
|
disable(): Promise<void>;
|
|
727
762
|
debug(enabled?: boolean): void;
|
|
728
763
|
capture(props: EventMessage): void;
|
|
764
|
+
captureImmediate(props: EventMessage): Promise<void>;
|
|
729
765
|
identify({ distinctId, properties, disableGeoip }: IdentifyMessage): void;
|
|
766
|
+
identifyImmediate({ distinctId, properties, disableGeoip }: IdentifyMessage): Promise<void>;
|
|
730
767
|
alias(data: {
|
|
731
768
|
distinctId: string;
|
|
732
769
|
alias: string;
|
|
733
770
|
disableGeoip?: boolean;
|
|
734
771
|
}): void;
|
|
772
|
+
aliasImmediate(data: {
|
|
773
|
+
distinctId: string;
|
|
774
|
+
alias: string;
|
|
775
|
+
disableGeoip?: boolean;
|
|
776
|
+
}): Promise<void>;
|
|
735
777
|
isLocalEvaluationReady(): boolean;
|
|
736
778
|
waitForLocalEvaluationReady(timeoutMs?: number): Promise<boolean>;
|
|
737
779
|
getFeatureFlag(key: string, distinctId: string, options?: {
|
package/lib/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { posix, dirname, sep } from 'path';
|
|
2
2
|
|
|
3
|
-
var version = "4.
|
|
3
|
+
var version = "4.15.0";
|
|
4
4
|
|
|
5
5
|
var PostHogPersistedProperty;
|
|
6
6
|
(function (PostHogPersistedProperty) {
|
|
@@ -256,6 +256,7 @@ const NEW_FLAGS_EXCLUDED_HASHES = new Set([
|
|
|
256
256
|
'fc80b8e2',
|
|
257
257
|
'75cc0998',
|
|
258
258
|
]);
|
|
259
|
+
const STRING_FORMAT = 'utf8';
|
|
259
260
|
function assert(truthyValue, message) {
|
|
260
261
|
if (!truthyValue || typeof truthyValue !== 'string' || isEmpty(truthyValue)) {
|
|
261
262
|
throw new Error(message);
|
|
@@ -1194,11 +1195,21 @@ const uuidv7 = () => uuidv7obj().toString();
|
|
|
1194
1195
|
const uuidv7obj = () => (defaultGenerator || (defaultGenerator = new V7Generator())).generate();
|
|
1195
1196
|
|
|
1196
1197
|
class PostHogFetchHttpError extends Error {
|
|
1197
|
-
constructor(response) {
|
|
1198
|
-
super('HTTP error while fetching PostHog: ' + response.status);
|
|
1198
|
+
constructor(response, reqByteLength) {
|
|
1199
|
+
super('HTTP error while fetching PostHog: status=' + response.status + ', reqByteLength=' + reqByteLength);
|
|
1199
1200
|
this.response = response;
|
|
1201
|
+
this.reqByteLength = reqByteLength;
|
|
1200
1202
|
this.name = 'PostHogFetchHttpError';
|
|
1201
1203
|
}
|
|
1204
|
+
get status() {
|
|
1205
|
+
return this.response.status;
|
|
1206
|
+
}
|
|
1207
|
+
get text() {
|
|
1208
|
+
return this.response.text();
|
|
1209
|
+
}
|
|
1210
|
+
get json() {
|
|
1211
|
+
return this.response.json();
|
|
1212
|
+
}
|
|
1202
1213
|
}
|
|
1203
1214
|
class PostHogFetchNetworkError extends Error {
|
|
1204
1215
|
constructor(error) {
|
|
@@ -1210,6 +1221,20 @@ class PostHogFetchNetworkError extends Error {
|
|
|
1210
1221
|
this.name = 'PostHogFetchNetworkError';
|
|
1211
1222
|
}
|
|
1212
1223
|
}
|
|
1224
|
+
async function logFlushError(err) {
|
|
1225
|
+
if (err instanceof PostHogFetchHttpError) {
|
|
1226
|
+
let text = '';
|
|
1227
|
+
try {
|
|
1228
|
+
text = await err.text;
|
|
1229
|
+
}
|
|
1230
|
+
catch { }
|
|
1231
|
+
console.error(`Error while flushing PostHog: message=${err.message}, response body=${text}`, err);
|
|
1232
|
+
}
|
|
1233
|
+
else {
|
|
1234
|
+
console.error('Error while flushing PostHog', err);
|
|
1235
|
+
}
|
|
1236
|
+
return Promise.resolve();
|
|
1237
|
+
}
|
|
1213
1238
|
function isPostHogFetchError(err) {
|
|
1214
1239
|
return typeof err === 'object' && (err instanceof PostHogFetchHttpError || err instanceof PostHogFetchNetworkError);
|
|
1215
1240
|
}
|
|
@@ -1343,12 +1368,26 @@ class PostHogCoreStateless {
|
|
|
1343
1368
|
this.enqueue('identify', payload, options);
|
|
1344
1369
|
});
|
|
1345
1370
|
}
|
|
1371
|
+
async identifyStatelessImmediate(distinctId, properties, options) {
|
|
1372
|
+
const payload = {
|
|
1373
|
+
...this.buildPayload({
|
|
1374
|
+
distinct_id: distinctId,
|
|
1375
|
+
event: '$identify',
|
|
1376
|
+
properties,
|
|
1377
|
+
}),
|
|
1378
|
+
};
|
|
1379
|
+
await this.sendImmediate('identify', payload, options);
|
|
1380
|
+
}
|
|
1346
1381
|
captureStateless(distinctId, event, properties, options) {
|
|
1347
1382
|
this.wrap(() => {
|
|
1348
1383
|
const payload = this.buildPayload({ distinct_id: distinctId, event, properties });
|
|
1349
1384
|
this.enqueue('capture', payload, options);
|
|
1350
1385
|
});
|
|
1351
1386
|
}
|
|
1387
|
+
async captureStatelessImmediate(distinctId, event, properties, options) {
|
|
1388
|
+
const payload = this.buildPayload({ distinct_id: distinctId, event, properties });
|
|
1389
|
+
await this.sendImmediate('capture', payload, options);
|
|
1390
|
+
}
|
|
1352
1391
|
aliasStateless(alias, distinctId, properties, options) {
|
|
1353
1392
|
this.wrap(() => {
|
|
1354
1393
|
const payload = this.buildPayload({
|
|
@@ -1363,6 +1402,18 @@ class PostHogCoreStateless {
|
|
|
1363
1402
|
this.enqueue('alias', payload, options);
|
|
1364
1403
|
});
|
|
1365
1404
|
}
|
|
1405
|
+
async aliasStatelessImmediate(alias, distinctId, properties, options) {
|
|
1406
|
+
const payload = this.buildPayload({
|
|
1407
|
+
event: '$create_alias',
|
|
1408
|
+
distinct_id: distinctId,
|
|
1409
|
+
properties: {
|
|
1410
|
+
...(properties || {}),
|
|
1411
|
+
distinct_id: distinctId,
|
|
1412
|
+
alias,
|
|
1413
|
+
},
|
|
1414
|
+
});
|
|
1415
|
+
await this.sendImmediate('alias', payload, options);
|
|
1416
|
+
}
|
|
1366
1417
|
/***
|
|
1367
1418
|
*** GROUPS
|
|
1368
1419
|
***/
|
|
@@ -1606,25 +1657,7 @@ class PostHogCoreStateless {
|
|
|
1606
1657
|
this._events.emit(type, `Library is disabled. Not sending event. To re-enable, call posthog.optIn()`);
|
|
1607
1658
|
return;
|
|
1608
1659
|
}
|
|
1609
|
-
const message =
|
|
1610
|
-
..._message,
|
|
1611
|
-
type: type,
|
|
1612
|
-
library: this.getLibraryId(),
|
|
1613
|
-
library_version: this.getLibraryVersion(),
|
|
1614
|
-
timestamp: options?.timestamp ? options?.timestamp : currentISOTime(),
|
|
1615
|
-
uuid: options?.uuid ? options.uuid : uuidv7(),
|
|
1616
|
-
};
|
|
1617
|
-
const addGeoipDisableProperty = options?.disableGeoip ?? this.disableGeoip;
|
|
1618
|
-
if (addGeoipDisableProperty) {
|
|
1619
|
-
if (!message.properties) {
|
|
1620
|
-
message.properties = {};
|
|
1621
|
-
}
|
|
1622
|
-
message['properties']['$geoip_disable'] = true;
|
|
1623
|
-
}
|
|
1624
|
-
if (message.distinctId) {
|
|
1625
|
-
message.distinct_id = message.distinctId;
|
|
1626
|
-
delete message.distinctId;
|
|
1627
|
-
}
|
|
1660
|
+
const message = this.prepareMessage(type, _message, options);
|
|
1628
1661
|
const queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
|
|
1629
1662
|
if (queue.length >= this.maxQueueSize) {
|
|
1630
1663
|
queue.shift();
|
|
@@ -1642,6 +1675,73 @@ class PostHogCoreStateless {
|
|
|
1642
1675
|
}
|
|
1643
1676
|
});
|
|
1644
1677
|
}
|
|
1678
|
+
async sendImmediate(type, _message, options) {
|
|
1679
|
+
if (this.disabled) {
|
|
1680
|
+
this.logMsgIfDebug(() => console.warn('[PostHog] The client is disabled'));
|
|
1681
|
+
return;
|
|
1682
|
+
}
|
|
1683
|
+
if (!this._isInitialized) {
|
|
1684
|
+
await this._initPromise;
|
|
1685
|
+
}
|
|
1686
|
+
if (this.optedOut) {
|
|
1687
|
+
this._events.emit(type, `Library is disabled. Not sending event. To re-enable, call posthog.optIn()`);
|
|
1688
|
+
return;
|
|
1689
|
+
}
|
|
1690
|
+
const data = {
|
|
1691
|
+
api_key: this.apiKey,
|
|
1692
|
+
batch: [this.prepareMessage(type, _message, options)],
|
|
1693
|
+
sent_at: currentISOTime(),
|
|
1694
|
+
};
|
|
1695
|
+
if (this.historicalMigration) {
|
|
1696
|
+
data.historical_migration = true;
|
|
1697
|
+
}
|
|
1698
|
+
const payload = JSON.stringify(data);
|
|
1699
|
+
const url = this.captureMode === 'form'
|
|
1700
|
+
? `${this.host}/e/?ip=1&_=${currentTimestamp()}&v=${this.getLibraryVersion()}`
|
|
1701
|
+
: `${this.host}/batch/`;
|
|
1702
|
+
const fetchOptions = this.captureMode === 'form'
|
|
1703
|
+
? {
|
|
1704
|
+
method: 'POST',
|
|
1705
|
+
mode: 'no-cors',
|
|
1706
|
+
credentials: 'omit',
|
|
1707
|
+
headers: { ...this.getCustomHeaders(), 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
1708
|
+
body: `data=${encodeURIComponent(LZString.compressToBase64(payload))}&compression=lz64`,
|
|
1709
|
+
}
|
|
1710
|
+
: {
|
|
1711
|
+
method: 'POST',
|
|
1712
|
+
headers: { ...this.getCustomHeaders(), 'Content-Type': 'application/json' },
|
|
1713
|
+
body: payload,
|
|
1714
|
+
};
|
|
1715
|
+
try {
|
|
1716
|
+
await this.fetchWithRetry(url, fetchOptions);
|
|
1717
|
+
}
|
|
1718
|
+
catch (err) {
|
|
1719
|
+
this._events.emit('error', err);
|
|
1720
|
+
throw err;
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
prepareMessage(type, _message, options) {
|
|
1724
|
+
const message = {
|
|
1725
|
+
..._message,
|
|
1726
|
+
type: type,
|
|
1727
|
+
library: this.getLibraryId(),
|
|
1728
|
+
library_version: this.getLibraryVersion(),
|
|
1729
|
+
timestamp: options?.timestamp ? options?.timestamp : currentISOTime(),
|
|
1730
|
+
uuid: options?.uuid ? options.uuid : uuidv7(),
|
|
1731
|
+
};
|
|
1732
|
+
const addGeoipDisableProperty = options?.disableGeoip ?? this.disableGeoip;
|
|
1733
|
+
if (addGeoipDisableProperty) {
|
|
1734
|
+
if (!message.properties) {
|
|
1735
|
+
message.properties = {};
|
|
1736
|
+
}
|
|
1737
|
+
message['properties']['$geoip_disable'] = true;
|
|
1738
|
+
}
|
|
1739
|
+
if (message.distinctId) {
|
|
1740
|
+
message.distinct_id = message.distinctId;
|
|
1741
|
+
delete message.distinctId;
|
|
1742
|
+
}
|
|
1743
|
+
return message;
|
|
1744
|
+
}
|
|
1645
1745
|
clearFlushTimer() {
|
|
1646
1746
|
if (this._flushTimer) {
|
|
1647
1747
|
clearTimeout(this._flushTimer);
|
|
@@ -1653,7 +1753,9 @@ class PostHogCoreStateless {
|
|
|
1653
1753
|
* Avoids unnecessary promise errors
|
|
1654
1754
|
*/
|
|
1655
1755
|
flushBackground() {
|
|
1656
|
-
void this.flush().catch(() => {
|
|
1756
|
+
void this.flush().catch(async (err) => {
|
|
1757
|
+
await logFlushError(err);
|
|
1758
|
+
});
|
|
1657
1759
|
}
|
|
1658
1760
|
async flush() {
|
|
1659
1761
|
if (!this.flushPromise) {
|
|
@@ -1737,6 +1839,8 @@ class PostHogCoreStateless {
|
|
|
1737
1839
|
setTimeout(() => ctrl.abort(), ms);
|
|
1738
1840
|
return ctrl.signal;
|
|
1739
1841
|
});
|
|
1842
|
+
const body = options.body ? options.body : '';
|
|
1843
|
+
const reqByteLength = Buffer.byteLength(body, STRING_FORMAT);
|
|
1740
1844
|
return await retriable(async () => {
|
|
1741
1845
|
let res = null;
|
|
1742
1846
|
try {
|
|
@@ -1754,7 +1858,7 @@ class PostHogCoreStateless {
|
|
|
1754
1858
|
// https://developer.mozilla.org/en-US/docs/Web/API/Request/mode#no-cors
|
|
1755
1859
|
const isNoCors = options.mode === 'no-cors';
|
|
1756
1860
|
if (!isNoCors && (res.status < 200 || res.status >= 400)) {
|
|
1757
|
-
throw new PostHogFetchHttpError(res);
|
|
1861
|
+
throw new PostHogFetchHttpError(res, reqByteLength);
|
|
1758
1862
|
}
|
|
1759
1863
|
return res;
|
|
1760
1864
|
}, { ...this._retryOptions, ...retryOptions });
|
|
@@ -1786,7 +1890,7 @@ class PostHogCoreStateless {
|
|
|
1786
1890
|
if (!isPostHogFetchError(e)) {
|
|
1787
1891
|
throw e;
|
|
1788
1892
|
}
|
|
1789
|
-
|
|
1893
|
+
await logFlushError(e);
|
|
1790
1894
|
}
|
|
1791
1895
|
};
|
|
1792
1896
|
return Promise.race([
|
|
@@ -3667,6 +3771,79 @@ class PostHog extends PostHogCoreStateless {
|
|
|
3667
3771
|
});
|
|
3668
3772
|
this.addPendingPromise(capturePromise);
|
|
3669
3773
|
}
|
|
3774
|
+
async captureImmediate(props) {
|
|
3775
|
+
if (typeof props === 'string') {
|
|
3776
|
+
this.logMsgIfDebug(() => console.warn('Called capture() with a string as the first argument when an object was expected.'));
|
|
3777
|
+
}
|
|
3778
|
+
const {
|
|
3779
|
+
distinctId,
|
|
3780
|
+
event,
|
|
3781
|
+
properties,
|
|
3782
|
+
groups,
|
|
3783
|
+
sendFeatureFlags,
|
|
3784
|
+
timestamp,
|
|
3785
|
+
disableGeoip,
|
|
3786
|
+
uuid
|
|
3787
|
+
} = props;
|
|
3788
|
+
const _capture = props => {
|
|
3789
|
+
return super.captureStatelessImmediate(distinctId, event, props, {
|
|
3790
|
+
timestamp,
|
|
3791
|
+
disableGeoip,
|
|
3792
|
+
uuid
|
|
3793
|
+
});
|
|
3794
|
+
};
|
|
3795
|
+
const _getFlags = async (distinctId, groups, disableGeoip) => {
|
|
3796
|
+
return (await super.getFeatureFlagsStateless(distinctId, groups, undefined, undefined, disableGeoip)).flags;
|
|
3797
|
+
};
|
|
3798
|
+
const capturePromise = Promise.resolve().then(async () => {
|
|
3799
|
+
if (sendFeatureFlags) {
|
|
3800
|
+
// If we are sending feature flags, we need to make sure we have the latest flags
|
|
3801
|
+
// return await super.getFeatureFlagsStateless(distinctId, groups, undefined, undefined, disableGeoip)
|
|
3802
|
+
return await _getFlags(distinctId, groups, disableGeoip);
|
|
3803
|
+
}
|
|
3804
|
+
if (event === '$feature_flag_called') {
|
|
3805
|
+
// If we're capturing a $feature_flag_called event, we don't want to enrich the event with cached flags that may be out of date.
|
|
3806
|
+
return {};
|
|
3807
|
+
}
|
|
3808
|
+
if ((this.featureFlagsPoller?.featureFlags?.length || 0) > 0) {
|
|
3809
|
+
// Otherwise we may as well check for the flags locally and include them if they are already loaded
|
|
3810
|
+
const groupsWithStringValues = {};
|
|
3811
|
+
for (const [key, value] of Object.entries(groups || {})) {
|
|
3812
|
+
groupsWithStringValues[key] = String(value);
|
|
3813
|
+
}
|
|
3814
|
+
return await this.getAllFlags(distinctId, {
|
|
3815
|
+
groups: groupsWithStringValues,
|
|
3816
|
+
disableGeoip,
|
|
3817
|
+
onlyEvaluateLocally: true
|
|
3818
|
+
});
|
|
3819
|
+
}
|
|
3820
|
+
return {};
|
|
3821
|
+
}).then(flags => {
|
|
3822
|
+
// Derive the relevant flag properties to add
|
|
3823
|
+
const additionalProperties = {};
|
|
3824
|
+
if (flags) {
|
|
3825
|
+
for (const [feature, variant] of Object.entries(flags)) {
|
|
3826
|
+
additionalProperties[`$feature/${feature}`] = variant;
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
3829
|
+
const activeFlags = Object.keys(flags || {}).filter(flag => flags?.[flag] !== false).sort();
|
|
3830
|
+
if (activeFlags.length > 0) {
|
|
3831
|
+
additionalProperties['$active_feature_flags'] = activeFlags;
|
|
3832
|
+
}
|
|
3833
|
+
return additionalProperties;
|
|
3834
|
+
}).catch(() => {
|
|
3835
|
+
// Something went wrong getting the flag info - we should capture the event anyways
|
|
3836
|
+
return {};
|
|
3837
|
+
}).then(additionalProperties => {
|
|
3838
|
+
// No matter what - capture the event
|
|
3839
|
+
_capture({
|
|
3840
|
+
...additionalProperties,
|
|
3841
|
+
...properties,
|
|
3842
|
+
$groups: groups
|
|
3843
|
+
});
|
|
3844
|
+
});
|
|
3845
|
+
await capturePromise;
|
|
3846
|
+
}
|
|
3670
3847
|
identify({
|
|
3671
3848
|
distinctId,
|
|
3672
3849
|
properties,
|
|
@@ -3685,11 +3862,33 @@ class PostHog extends PostHogCoreStateless {
|
|
|
3685
3862
|
disableGeoip
|
|
3686
3863
|
});
|
|
3687
3864
|
}
|
|
3865
|
+
async identifyImmediate({
|
|
3866
|
+
distinctId,
|
|
3867
|
+
properties,
|
|
3868
|
+
disableGeoip
|
|
3869
|
+
}) {
|
|
3870
|
+
// promote $set and $set_once to top level
|
|
3871
|
+
const userPropsOnce = properties?.$set_once;
|
|
3872
|
+
delete properties?.$set_once;
|
|
3873
|
+
// if no $set is provided we assume all properties are $set
|
|
3874
|
+
const userProps = properties?.$set || properties;
|
|
3875
|
+
await super.identifyStatelessImmediate(distinctId, {
|
|
3876
|
+
$set: userProps,
|
|
3877
|
+
$set_once: userPropsOnce
|
|
3878
|
+
}, {
|
|
3879
|
+
disableGeoip
|
|
3880
|
+
});
|
|
3881
|
+
}
|
|
3688
3882
|
alias(data) {
|
|
3689
3883
|
super.aliasStateless(data.alias, data.distinctId, undefined, {
|
|
3690
3884
|
disableGeoip: data.disableGeoip
|
|
3691
3885
|
});
|
|
3692
3886
|
}
|
|
3887
|
+
async aliasImmediate(data) {
|
|
3888
|
+
await super.aliasStatelessImmediate(data.alias, data.distinctId, undefined, {
|
|
3889
|
+
disableGeoip: data.disableGeoip
|
|
3890
|
+
});
|
|
3891
|
+
}
|
|
3693
3892
|
isLocalEvaluationReady() {
|
|
3694
3893
|
return this.featureFlagsPoller?.isLocalEvaluationReady() ?? false;
|
|
3695
3894
|
}
|