@lowdefy/plugin-posthog 0.0.0-experimental-20260925135632

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 (39) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +81 -0
  3. package/dist/actions/PostHogAlias.js +31 -0
  4. package/dist/actions/PostHogAlias.schema.js +31 -0
  5. package/dist/actions/PostHogCapture.js +48 -0
  6. package/dist/actions/PostHogCapture.schema.js +42 -0
  7. package/dist/actions/PostHogCapturePageLeave.js +33 -0
  8. package/dist/actions/PostHogCapturePageLeave.schema.js +27 -0
  9. package/dist/actions/PostHogFeatureFlag.js +51 -0
  10. package/dist/actions/PostHogFeatureFlag.schema.js +42 -0
  11. package/dist/actions/PostHogGroup.js +38 -0
  12. package/dist/actions/PostHogGroup.schema.js +41 -0
  13. package/dist/actions/PostHogIdentify.js +61 -0
  14. package/dist/actions/PostHogIdentify.schema.js +38 -0
  15. package/dist/actions/PostHogInit.js +66 -0
  16. package/dist/actions/PostHogInit.schema.js +70 -0
  17. package/dist/actions/PostHogOptIn.js +28 -0
  18. package/dist/actions/PostHogOptIn.schema.js +17 -0
  19. package/dist/actions/PostHogOptOut.js +27 -0
  20. package/dist/actions/PostHogOptOut.schema.js +17 -0
  21. package/dist/actions/PostHogPageview.js +35 -0
  22. package/dist/actions/PostHogPageview.schema.js +27 -0
  23. package/dist/actions/PostHogReloadFeatureFlags.js +61 -0
  24. package/dist/actions/PostHogReloadFeatureFlags.schema.js +28 -0
  25. package/dist/actions/PostHogReset.js +31 -0
  26. package/dist/actions/PostHogReset.schema.js +27 -0
  27. package/dist/actions/PostHogSetPersonProperties.js +39 -0
  28. package/dist/actions/PostHogSetPersonProperties.schema.js +43 -0
  29. package/dist/actions.js +27 -0
  30. package/dist/lib/cleanProperties.js +22 -0
  31. package/dist/lib/getPostHog.js +35 -0
  32. package/dist/lib/initPostHog.js +45 -0
  33. package/dist/lib/loadPostHog.js +37 -0
  34. package/dist/lib/postHogState.js +32 -0
  35. package/dist/lib/warnUninitialized.js +25 -0
  36. package/dist/schemas.js +27 -0
  37. package/dist/test/resetPostHogState.js +25 -0
  38. package/dist/types.js +31 -0
  39. package/package.json +60 -0
@@ -0,0 +1,43 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ export default {
16
+ type: 'object',
17
+ params: {
18
+ type: 'object',
19
+ properties: {
20
+ set: {
21
+ type: 'object',
22
+ description: 'Person properties to set.'
23
+ },
24
+ setOnce: {
25
+ type: 'object',
26
+ description: 'Person properties that are only set if the person does not have them yet.'
27
+ }
28
+ },
29
+ anyOf: [
30
+ {
31
+ required: [
32
+ 'set'
33
+ ]
34
+ },
35
+ {
36
+ required: [
37
+ 'setOnce'
38
+ ]
39
+ }
40
+ ],
41
+ additionalProperties: false
42
+ }
43
+ };
@@ -0,0 +1,27 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ export { default as PostHogAlias } from './actions/PostHogAlias.js';
16
+ export { default as PostHogCapture } from './actions/PostHogCapture.js';
17
+ export { default as PostHogCapturePageLeave } from './actions/PostHogCapturePageLeave.js';
18
+ export { default as PostHogFeatureFlag } from './actions/PostHogFeatureFlag.js';
19
+ export { default as PostHogGroup } from './actions/PostHogGroup.js';
20
+ export { default as PostHogIdentify } from './actions/PostHogIdentify.js';
21
+ export { default as PostHogInit } from './actions/PostHogInit.js';
22
+ export { default as PostHogOptIn } from './actions/PostHogOptIn.js';
23
+ export { default as PostHogOptOut } from './actions/PostHogOptOut.js';
24
+ export { default as PostHogPageview } from './actions/PostHogPageview.js';
25
+ export { default as PostHogReloadFeatureFlags } from './actions/PostHogReloadFeatureFlags.js';
26
+ export { default as PostHogReset } from './actions/PostHogReset.js';
27
+ export { default as PostHogSetPersonProperties } from './actions/PostHogSetPersonProperties.js';
@@ -0,0 +1,22 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import { type } from '@lowdefy/helpers';
16
+ // Drops null and undefined values so an absent property does not overwrite a
17
+ // value PostHog already has for the person.
18
+ function cleanProperties(properties) {
19
+ if (!type.isObject(properties)) return {};
20
+ return Object.fromEntries(Object.entries(properties).filter(([, value])=>!type.isNone(value)));
21
+ }
22
+ export default cleanProperties;
@@ -0,0 +1,35 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import postHogState from './postHogState.js';
16
+ import warnUninitialized from './warnUninitialized.js';
17
+ // Returns the posthog-js instance, or null when the calling action should do
18
+ // nothing. Analytics must never break an app, so a disabled, failed or missing
19
+ // PostHog is never an error here. Callers validate their params first, so
20
+ // invalid config is still caught in environments where PostHog is off.
21
+ async function getPostHog({ action }) {
22
+ if (postHogState.status === 'loading') {
23
+ await postHogState.loading;
24
+ }
25
+ if (postHogState.status === 'enabled') {
26
+ return postHogState.client;
27
+ }
28
+ if (postHogState.status === 'uninitialized') {
29
+ warnUninitialized({
30
+ action
31
+ });
32
+ }
33
+ return null;
34
+ }
35
+ export default getPostHog;
@@ -0,0 +1,45 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import loadPostHog from './loadPostHog.js';
16
+ import postHogState from './postHogState.js';
17
+ // PostHogInit runs from every page's onInit, so a repeat call with the same
18
+ // params must be a no-op. A disabled PostHog was never loaded, so a later call
19
+ // with enabled: true may still load it.
20
+ async function initPostHog({ apiKey, config, enabled, superProperties }) {
21
+ const { status } = postHogState;
22
+ if (enabled === false) {
23
+ if (status === 'uninitialized' || status === 'disabled') {
24
+ postHogState.status = 'disabled';
25
+ return;
26
+ }
27
+ throw new Error('PostHogInit was called with "enabled: false" after PostHog was already initialised. Use the same PostHogInit params on every page, and PostHogOptOut to stop capturing for a person.');
28
+ }
29
+ if (status === 'uninitialized' || status === 'disabled') {
30
+ postHogState.apiKey = apiKey;
31
+ postHogState.status = 'loading';
32
+ postHogState.loading = loadPostHog({
33
+ apiKey,
34
+ config,
35
+ superProperties
36
+ });
37
+ await postHogState.loading;
38
+ return;
39
+ }
40
+ if (postHogState.apiKey !== apiKey) {
41
+ throw new Error(`PostHogInit was already called with a different "apiKey". PostHog can only be initialised once per browser session. Received ${JSON.stringify(apiKey)}.`);
42
+ }
43
+ await postHogState.loading;
44
+ }
45
+ export default initPostHog;
@@ -0,0 +1,37 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import postHogState from './postHogState.js';
16
+ // posthog-js is imported here, and only here, so an app that runs with
17
+ // enabled: false never downloads or runs the SDK.
18
+ async function loadPostHog({ apiKey, config, superProperties = {} }) {
19
+ let posthog;
20
+ try {
21
+ ({ default: posthog } = await import('posthog-js'));
22
+ } catch (error) {
23
+ // The SDK chunk failed to download, for example on a flaky network.
24
+ // Analytics must never break an app, so the other actions become no-ops.
25
+ postHogState.status = 'failed';
26
+ // eslint-disable-next-line no-console
27
+ console.warn('PostHogInit could not load posthog-js. PostHog actions will do nothing.', error);
28
+ return;
29
+ }
30
+ posthog.init(apiKey, config);
31
+ if (Object.keys(superProperties).length > 0) {
32
+ posthog.register(superProperties);
33
+ }
34
+ postHogState.client = posthog;
35
+ postHogState.status = 'enabled';
36
+ }
37
+ export default loadPostHog;
@@ -0,0 +1,32 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ // The singleton behind every action in this package. PostHogInit fills it in
16
+ // once per browser session; every other action reads it.
17
+ //
18
+ // status is one of:
19
+ // - uninitialized: PostHogInit has not run. Actions do nothing and warn once,
20
+ // because a missing PostHogInit is a config mistake.
21
+ // - disabled: PostHogInit ran with enabled: false. Actions do nothing, silently.
22
+ // - loading: PostHogInit is downloading posthog-js. Actions wait for it.
23
+ // - failed: posthog-js could not be downloaded. Actions do nothing, silently.
24
+ // - enabled: client is the initialised posthog-js instance.
25
+ const postHogState = {
26
+ apiKey: null,
27
+ client: null,
28
+ loading: null,
29
+ status: 'uninitialized',
30
+ warnedUninitialized: false
31
+ };
32
+ export default postHogState;
@@ -0,0 +1,25 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import postHogState from './postHogState.js';
16
+ // A PostHog action running before PostHogInit is a config mistake, but
17
+ // analytics must never throw, so the browser console is the only place left to
18
+ // report it. Once is enough to point at the fix without flooding the console.
19
+ function warnUninitialized({ action }) {
20
+ if (postHogState.warnedUninitialized) return;
21
+ postHogState.warnedUninitialized = true;
22
+ // eslint-disable-next-line no-console
23
+ console.warn(`${action} ran before PostHogInit, so it did nothing. Run PostHogInit in the page onInit event, with "enabled: false" where analytics should be off.`);
24
+ }
25
+ export default warnUninitialized;
@@ -0,0 +1,27 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ export { default as PostHogAlias } from './actions/PostHogAlias.schema.js';
16
+ export { default as PostHogCapture } from './actions/PostHogCapture.schema.js';
17
+ export { default as PostHogCapturePageLeave } from './actions/PostHogCapturePageLeave.schema.js';
18
+ export { default as PostHogFeatureFlag } from './actions/PostHogFeatureFlag.schema.js';
19
+ export { default as PostHogGroup } from './actions/PostHogGroup.schema.js';
20
+ export { default as PostHogIdentify } from './actions/PostHogIdentify.schema.js';
21
+ export { default as PostHogInit } from './actions/PostHogInit.schema.js';
22
+ export { default as PostHogOptIn } from './actions/PostHogOptIn.schema.js';
23
+ export { default as PostHogOptOut } from './actions/PostHogOptOut.schema.js';
24
+ export { default as PostHogPageview } from './actions/PostHogPageview.schema.js';
25
+ export { default as PostHogReloadFeatureFlags } from './actions/PostHogReloadFeatureFlags.schema.js';
26
+ export { default as PostHogReset } from './actions/PostHogReset.schema.js';
27
+ export { default as PostHogSetPersonProperties } from './actions/PostHogSetPersonProperties.schema.js';
@@ -0,0 +1,25 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import postHogState from '../lib/postHogState.js';
16
+ // The singleton lives for the life of the module registry, so each test starts
17
+ // by putting it back to its "PostHogInit has not run" state.
18
+ function resetPostHogState() {
19
+ postHogState.apiKey = null;
20
+ postHogState.client = null;
21
+ postHogState.loading = null;
22
+ postHogState.status = 'uninitialized';
23
+ postHogState.warnedUninitialized = false;
24
+ }
25
+ export default resetPostHogState;
package/dist/types.js ADDED
@@ -0,0 +1,31 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ export default {
16
+ actions: [
17
+ 'PostHogAlias',
18
+ 'PostHogCapture',
19
+ 'PostHogCapturePageLeave',
20
+ 'PostHogFeatureFlag',
21
+ 'PostHogGroup',
22
+ 'PostHogIdentify',
23
+ 'PostHogInit',
24
+ 'PostHogOptIn',
25
+ 'PostHogOptOut',
26
+ 'PostHogPageview',
27
+ 'PostHogReloadFeatureFlags',
28
+ 'PostHogReset',
29
+ 'PostHogSetPersonProperties'
30
+ ]
31
+ };
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@lowdefy/plugin-posthog",
3
+ "version": "0.0.0-experimental-20260925135632",
4
+ "license": "Apache-2.0",
5
+ "description": "Lowdefy PostHog product analytics plugin: initialise posthog-js, capture events, identify people and groups, manage consent and read feature flags.",
6
+ "homepage": "https://lowdefy.com",
7
+ "keywords": [
8
+ "lowdefy",
9
+ "lowdefy actions",
10
+ "lowdefy plugin",
11
+ "posthog",
12
+ "analytics"
13
+ ],
14
+ "bugs": {
15
+ "url": "https://github.com/lowdefy/lowdefy/issues"
16
+ },
17
+ "contributors": [
18
+ {
19
+ "name": "Gerrie van Wyk",
20
+ "url": "https://github.com/Gervwyk"
21
+ }
22
+ ],
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/lowdefy/lowdefy.git"
26
+ },
27
+ "type": "module",
28
+ "sideEffects": [
29
+ "**/*.css"
30
+ ],
31
+ "exports": {
32
+ "./actions": "./dist/actions.js",
33
+ "./schemas": "./dist/schemas.js",
34
+ "./types": "./dist/types.js"
35
+ },
36
+ "files": [
37
+ "dist/*"
38
+ ],
39
+ "dependencies": {
40
+ "@lowdefy/helpers": "0.0.0-experimental-20260925135632",
41
+ "posthog-js": "1.434.7"
42
+ },
43
+ "devDependencies": {
44
+ "@jest/globals": "28.1.3",
45
+ "@lowdefy/node-utils": "0.0.0-experimental-20260925135632",
46
+ "@swc/cli": "0.8.1",
47
+ "@swc/core": "1.15.32",
48
+ "@swc/jest": "0.2.39",
49
+ "jest": "28.1.3",
50
+ "jest-environment-jsdom": "28.1.3"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
54
+ },
55
+ "scripts": {
56
+ "build": "swc src --out-dir dist --config-file ../../../../.swcrc --cli-config-file ../../../../.swc-cli.json --copy-files",
57
+ "clean": "rm -rf dist",
58
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
59
+ }
60
+ }