@walkeros/server-destination-posthog 4.7.0-next-1790245733116 → 4.7.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 CHANGED
@@ -1,24 +1,35 @@
1
1
  # @walkeros/server-destination-posthog
2
2
 
3
- ## 4.7.0-next-1790245733116
3
+ ## 4.7.0
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - Updated dependencies [57788bc]
7
+ - 74821ed: Simulate records every vendor call through one recorder, `observeEnv`
8
+ from `@walkeros/core`, and runs offline: BigQuery, Data Manager and the
9
+ Sheets, GCS and S3 stores reach the network through `env`. Client and `Env`
10
+ types of BigQuery, Firehose, PostHog, SQS and Pub/Sub are structural.
11
+ `@walkeros/cli` exports `resolveExportName` and `selectDevExamples` and drops
12
+ `findExample` and `compareOutput`.
13
+ - Updated dependencies [74821ed]
8
14
  - Updated dependencies [06b498a]
9
- - Updated dependencies [f5a1cfd]
10
- - Updated dependencies [ef02916]
15
+ - Updated dependencies [74821ed]
16
+ - Updated dependencies [64b06de]
17
+ - Updated dependencies [4b4937f]
18
+ - Updated dependencies [74821ed]
19
+ - Updated dependencies [74821ed]
20
+ - Updated dependencies [74821ed]
11
21
  - Updated dependencies [06b498a]
12
- - Updated dependencies [ef02916]
13
- - Updated dependencies [2aebc53]
14
- - Updated dependencies [f5a1cfd]
15
- - Updated dependencies [f5a1cfd]
16
- - Updated dependencies [2aebc53]
17
- - Updated dependencies [8f8aea6]
18
- - Updated dependencies [2aebc53]
19
- - Updated dependencies [2aebc53]
20
- - @walkeros/core@4.7.0-next-1790245733116
21
- - @walkeros/server-core@4.7.0-next-1790245733116
22
+ - Updated dependencies [74821ed]
23
+ - Updated dependencies [74821ed]
24
+ - Updated dependencies [74821ed]
25
+ - Updated dependencies [74821ed]
26
+ - Updated dependencies [74821ed]
27
+ - Updated dependencies [e860006]
28
+ - Updated dependencies [74821ed]
29
+ - Updated dependencies [74821ed]
30
+ - Updated dependencies [4f89234]
31
+ - @walkeros/core@4.7.0
32
+ - @walkeros/server-core@4.7.0
22
33
 
23
34
  ## 4.6.1
24
35
 
package/dist/dev.d.mts CHANGED
@@ -41,7 +41,7 @@ interface Settings {
41
41
  /** PostHog project API key (phc_...) */
42
42
  apiKey: string;
43
43
  /** PostHog client instance, populated by init */
44
- client?: PostHog;
44
+ client?: PostHogClient;
45
45
  /** Destination-level identity mapping */
46
46
  identify?: Mapping$1.Value;
47
47
  /** Destination-level group mapping */
@@ -61,8 +61,21 @@ interface Settings {
61
61
  debug?: boolean;
62
62
  disabled?: boolean;
63
63
  }
64
+ /**
65
+ * The part of a PostHog client this destination calls. `PostHog` from
66
+ * `posthog-node` satisfies it, and so does an injected mock (tests, simulate)
67
+ * without a cast.
68
+ */
69
+ interface PostHogClient {
70
+ capture(props: Parameters<PostHog['capture']>[0]): void;
71
+ identify(props: Parameters<PostHog['identify']>[0]): void;
72
+ groupIdentify(props: Parameters<PostHog['groupIdentify']>[0]): void;
73
+ shutdown(): Promise<void> | void;
74
+ enable(): Promise<void> | void;
75
+ disable(): Promise<void> | void;
76
+ }
64
77
  interface Env extends DestinationServer.Env {
65
- PostHog?: typeof PostHog;
78
+ PostHog?: new (apiKey: string, options?: ConstructorParameters<typeof PostHog>[1]) => PostHogClient;
66
79
  }
67
80
 
68
81
  /**
package/dist/dev.d.ts CHANGED
@@ -41,7 +41,7 @@ interface Settings {
41
41
  /** PostHog project API key (phc_...) */
42
42
  apiKey: string;
43
43
  /** PostHog client instance, populated by init */
44
- client?: PostHog;
44
+ client?: PostHogClient;
45
45
  /** Destination-level identity mapping */
46
46
  identify?: Mapping$1.Value;
47
47
  /** Destination-level group mapping */
@@ -61,8 +61,21 @@ interface Settings {
61
61
  debug?: boolean;
62
62
  disabled?: boolean;
63
63
  }
64
+ /**
65
+ * The part of a PostHog client this destination calls. `PostHog` from
66
+ * `posthog-node` satisfies it, and so does an injected mock (tests, simulate)
67
+ * without a cast.
68
+ */
69
+ interface PostHogClient {
70
+ capture(props: Parameters<PostHog['capture']>[0]): void;
71
+ identify(props: Parameters<PostHog['identify']>[0]): void;
72
+ groupIdentify(props: Parameters<PostHog['groupIdentify']>[0]): void;
73
+ shutdown(): Promise<void> | void;
74
+ enable(): Promise<void> | void;
75
+ disable(): Promise<void> | void;
76
+ }
64
77
  interface Env extends DestinationServer.Env {
65
- PostHog?: typeof PostHog;
78
+ PostHog?: new (apiKey: string, options?: ConstructorParameters<typeof PostHog>[1]) => PostHogClient;
66
79
  }
67
80
 
68
81
  /**
package/dist/dev.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,t=Object.defineProperty,i=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,s=(e,i)=>{for(var o in i)t(e,o,{get:i[o],enumerable:!0})},a={};s(a,{examples:()=>y,schemas:()=>r}),module.exports=(e=a,((e,s,a,r)=>{if(s&&"object"==typeof s||"function"==typeof s)for(let p of o(s))n.call(e,p)||p===a||t(e,p,{get:()=>s[p],enumerable:!(r=i(s,p))||r.enumerable});return e})(t({},"__esModule",{value:!0}),e));var r={};s(r,{MappingSchema:()=>u,SettingsSchema:()=>c,mapping:()=>m,settings:()=>g});var p=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),c=l.z.object({apiKey:l.z.string().min(1).describe('PostHog project API key (starts with "phc_"). Find it in PostHog project settings.'),host:l.z.string().describe("PostHog API host. Defaults to https://us.i.posthog.com. Use https://eu.i.posthog.com for EU or your self-hosted URL.").optional(),flushAt:l.z.number().describe("Number of events queued before auto-flush. Default: 20.").optional(),flushInterval:l.z.number().describe("Milliseconds between periodic flushes. Default: 10000.").optional(),personalApiKey:l.z.string().describe("Personal API key (phx_...) for local feature flag evaluation.").optional(),featureFlagsPollingInterval:l.z.number().describe("Milliseconds between feature flag definition polls. Default: 30000.").optional(),disableGeoip:l.z.boolean().describe("Disable GeoIP lookups globally. Useful for GDPR compliance.").optional(),debug:l.z.boolean().describe("Enable PostHog SDK debug logging. Default: false.").optional(),identify:l.z.unknown().describe("walkerOS mapping value resolving to an identity object. Keys: distinctId, $set, $set_once. Resolved on every push (server is stateless).").optional(),group:l.z.unknown().describe("walkerOS mapping value resolving to a group object. Keys: type, key, properties. Resolved on every push.").optional(),include:l.z.array(l.z.string()).describe('Event sections to flatten into capture() properties (e.g. ["data", "globals"]).').optional()}),d=require("@walkeros/core/dev"),u=d.z.object({identify:d.z.unknown().describe("Per-event identity mapping. Resolves to { distinctId, $set?, $set_once? }. Fires client.identify() when $set/$set_once present.").optional(),group:d.z.unknown().describe("Group assignment. Resolves to { type, key, properties? }. Fires client.groupIdentify() when properties present, adds groups to capture().").optional()}),g=(0,p.zodToSchema)(c),m=(0,p.zodToSchema)(u),y={};s(y,{env:()=>h,step:()=>v});var h={};s(h,{push:()=>f,simulation:()=>b});var f={get PostHog(){return class{apiKey;options;calls;constructor(e,t){this.apiKey=e,this.options=t||{},this.calls=[]}capture(e){this.calls.push({method:"capture",args:[e]})}identify(e){this.calls.push({method:"identify",args:[e]})}groupIdentify(e){this.calls.push({method:"groupIdentify",args:[e]})}flush(){return this.calls.push({method:"flush",args:[]}),Promise.resolve()}async shutdown(){this.calls.push({method:"shutdown",args:[]})}enable(){this.calls.push({method:"enable",args:[]})}disable(){this.calls.push({method:"disable",args:[]})}}}},b=["call:client.capture","call:client.identify","call:client.groupIdentify","call:client.shutdown"],v={};s(v,{captureWithGroupContext:()=>z,captureWithInclude:()=>P,consentGrant:()=>$,consentRevoke:()=>A,defaultCapture:()=>_,groupIdentifyWithProperties:()=>I,identifyWithSetAndSetOnce:()=>k});var w=require("@walkeros/core"),_={title:"Default capture",description:"A walker event becomes a PostHog capture call with the user id as distinctId and no extra properties.",in:(0,w.getEvent)("product view",{timestamp:1700000100}),out:[["client.capture",{distinctId:"us3r",event:"product view",properties:{}}]]},P={title:"Capture with include",description:"Destination-level include flattens data and globals sections into prefixed PostHog event properties.",in:(0,w.getEvent)("order complete",{timestamp:1700000101}),configInclude:["data","globals"],out:[["client.capture",{distinctId:"us3r",event:"order complete",properties:{data_id:"0rd3r1d",data_currency:"EUR",data_shipping:5.22,data_taxes:73.76,data_total:555,globals_pagegroup:"shop"}}]]},k={title:"Identify with $set",description:"A user login fires PostHog identify with $set and $set_once person properties and skips the capture.",in:(0,w.getEvent)("user login",{timestamp:1700000102,data:{user_id:"new-user-123",email:"user@acme.com",plan:"premium"}}),mapping:{silent:!0,settings:{identify:{map:{distinctId:"data.user_id",$set:{map:{email:"data.email",plan:"data.plan"}},$set_once:{map:{first_login:"timestamp"}}}}}},out:[["client.identify",{distinctId:"new-user-123",properties:{$set:{email:"user@acme.com",plan:"premium"},$set_once:{first_login:1700000102}}}]]},I={title:"Group identify",description:"A company update fires PostHog groupIdentify with group type, key, and associated group properties.",in:(0,w.getEvent)("company update",{timestamp:1700000103,data:{company_id:"company_123",company_name:"Acme",plan:"enterprise"}}),mapping:{silent:!0,settings:{group:{map:{type:{value:"company"},key:"data.company_id",properties:{map:{name:"data.company_name",plan:"data.plan"}}}}}},out:[["client.groupIdentify",{groupType:"company",groupKey:"company_123",properties:{name:"Acme",plan:"enterprise"}}]]},z={title:"Capture with group",description:"A destination-level group mapping attaches the resolved group context to every PostHog capture call.",in:(0,w.getEvent)("page view",{timestamp:1700000104,globals:{pagegroup:"docs",company_id:"company_123"}}),settings:{group:{map:{type:{value:"company"},key:"globals.company_id"}}},out:[["client.capture",{distinctId:"us3r",event:"page view",properties:{},groups:{company:"company_123"}}]]},A={title:"Consent revoked",description:"A walker consent command with analytics denied calls client.disable on the PostHog client.",command:"consent",before:{analytics:!0},in:{analytics:!1},settings:{},out:[["client.enable"],["client.disable"]]},$={title:"Consent granted",description:"A walker consent command with analytics granted calls client.enable on the PostHog client.",command:"consent",in:{analytics:!0},settings:{},out:[["client.enable"]]};//# sourceMappingURL=dev.js.map
1
+ "use strict";var e,t=Object.defineProperty,o=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,n=(e,o)=>{for(var i in o)t(e,i,{get:o[i],enumerable:!0})},a={};n(a,{examples:()=>y,schemas:()=>r}),module.exports=(e=a,((e,n,a,r)=>{if(n&&"object"==typeof n||"function"==typeof n)for(let p of i(n))s.call(e,p)||p===a||t(e,p,{get:()=>n[p],enumerable:!(r=o(n,p))||r.enumerable});return e})(t({},"__esModule",{value:!0}),e));var r={};n(r,{MappingSchema:()=>u,SettingsSchema:()=>c,mapping:()=>m,settings:()=>g});var p=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),c=l.z.object({apiKey:l.z.string().min(1).describe('PostHog project API key (starts with "phc_"). Find it in PostHog project settings.'),host:l.z.string().describe("PostHog API host. Defaults to https://us.i.posthog.com. Use https://eu.i.posthog.com for EU or your self-hosted URL.").optional(),flushAt:l.z.number().describe("Number of events queued before auto-flush. Default: 20.").optional(),flushInterval:l.z.number().describe("Milliseconds between periodic flushes. Default: 10000.").optional(),personalApiKey:l.z.string().describe("Personal API key (phx_...) for local feature flag evaluation.").optional(),featureFlagsPollingInterval:l.z.number().describe("Milliseconds between feature flag definition polls. Default: 30000.").optional(),disableGeoip:l.z.boolean().describe("Disable GeoIP lookups globally. Useful for GDPR compliance.").optional(),debug:l.z.boolean().describe("Enable PostHog SDK debug logging. Default: false.").optional(),identify:l.z.unknown().describe("walkerOS mapping value resolving to an identity object. Keys: distinctId, $set, $set_once. Resolved on every push (server is stateless).").optional(),group:l.z.unknown().describe("walkerOS mapping value resolving to a group object. Keys: type, key, properties. Resolved on every push.").optional(),include:l.z.array(l.z.string()).describe('Event sections to flatten into capture() properties (e.g. ["data", "globals"]).').optional()}),d=require("@walkeros/core/dev"),u=d.z.object({identify:d.z.unknown().describe("Per-event identity mapping. Resolves to { distinctId, $set?, $set_once? }. Fires client.identify() when $set/$set_once present.").optional(),group:d.z.unknown().describe("Group assignment. Resolves to { type, key, properties? }. Fires client.groupIdentify() when properties present, adds groups to capture().").optional()}),g=(0,p.zodToSchema)(c),m=(0,p.zodToSchema)(u),y={};n(y,{env:()=>h,step:()=>v});var h={};n(h,{push:()=>f,simulation:()=>b});var f={get PostHog(){return class{apiKey;options;calls;constructor(e,t){this.apiKey=e,this.options=t||{},this.calls=[]}capture(e){this.calls.push({method:"capture",args:[e]})}identify(e){this.calls.push({method:"identify",args:[e]})}groupIdentify(e){this.calls.push({method:"groupIdentify",args:[e]})}flush(){return this.calls.push({method:"flush",args:[]}),Promise.resolve()}async shutdown(){this.calls.push({method:"shutdown",args:[]})}enable(){this.calls.push({method:"enable",args:[]})}disable(){this.calls.push({method:"disable",args:[]})}}}},b=["call:PostHog.capture","call:PostHog.identify","call:PostHog.groupIdentify","call:PostHog.shutdown"],v={};n(v,{captureWithGroupContext:()=>z,captureWithInclude:()=>_,consentGrant:()=>A,consentRevoke:()=>H,defaultCapture:()=>P,groupIdentifyWithProperties:()=>I,identifyWithSetAndSetOnce:()=>k});var w=require("@walkeros/core"),P={title:"Default capture",description:"A walker event becomes a PostHog capture call with the user id as distinctId and no extra properties.",in:(0,w.getEvent)("product view",{timestamp:1700000100}),out:[["client.capture",{distinctId:"us3r",event:"product view",properties:{}}]]},_={title:"Capture with include",description:"Destination-level include flattens data and globals sections into prefixed PostHog event properties.",in:(0,w.getEvent)("order complete",{timestamp:1700000101}),configInclude:["data","globals"],out:[["client.capture",{distinctId:"us3r",event:"order complete",properties:{data_id:"0rd3r1d",data_currency:"EUR",data_shipping:5.22,data_taxes:73.76,data_total:555,globals_pagegroup:"shop"}}]]},k={title:"Identify with $set",description:"A user login fires PostHog identify with $set and $set_once person properties and skips the capture.",in:(0,w.getEvent)("user login",{timestamp:1700000102,data:{user_id:"new-user-123",email:"user@acme.com",plan:"premium"}}),mapping:{silent:!0,settings:{identify:{map:{distinctId:"data.user_id",$set:{map:{email:"data.email",plan:"data.plan"}},$set_once:{map:{first_login:"timestamp"}}}}}},out:[["client.identify",{distinctId:"new-user-123",properties:{$set:{email:"user@acme.com",plan:"premium"},$set_once:{first_login:1700000102}}}]]},I={title:"Group identify",description:"A company update fires PostHog groupIdentify with group type, key, and associated group properties.",in:(0,w.getEvent)("company update",{timestamp:1700000103,data:{company_id:"company_123",company_name:"Acme",plan:"enterprise"}}),mapping:{silent:!0,settings:{group:{map:{type:{value:"company"},key:"data.company_id",properties:{map:{name:"data.company_name",plan:"data.plan"}}}}}},out:[["client.groupIdentify",{groupType:"company",groupKey:"company_123",properties:{name:"Acme",plan:"enterprise"}}]]},z={title:"Capture with group",description:"A destination-level group mapping attaches the resolved group context to every PostHog capture call.",in:(0,w.getEvent)("page view",{timestamp:1700000104,globals:{pagegroup:"docs",company_id:"company_123"}}),settings:{group:{map:{type:{value:"company"},key:"globals.company_id"}}},out:[["client.capture",{distinctId:"us3r",event:"page view",properties:{},groups:{company:"company_123"}}]]},H={title:"Consent revoked",description:"A walker consent command with analytics denied calls client.disable on the PostHog client.",command:"consent",before:{analytics:!0},in:{analytics:!1},settings:{},out:[["client.enable"],["client.disable"]]},A={title:"Consent granted",description:"A walker consent command with analytics granted calls client.enable on the PostHog client.",command:"consent",in:{analytics:!0},settings:{},out:[["client.enable"]]};//# sourceMappingURL=dev.js.map
package/dist/dev.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z.object({\n apiKey: z\n .string()\n .min(1)\n .describe(\n 'PostHog project API key (starts with \"phc_\"). Find it in PostHog project settings.',\n ),\n host: z\n .string()\n .describe(\n 'PostHog API host. Defaults to https://us.i.posthog.com. Use https://eu.i.posthog.com for EU or your self-hosted URL.',\n )\n .optional(),\n flushAt: z\n .number()\n .describe('Number of events queued before auto-flush. Default: 20.')\n .optional(),\n flushInterval: z\n .number()\n .describe('Milliseconds between periodic flushes. Default: 10000.')\n .optional(),\n personalApiKey: z\n .string()\n .describe('Personal API key (phx_...) for local feature flag evaluation.')\n .optional(),\n featureFlagsPollingInterval: z\n .number()\n .describe(\n 'Milliseconds between feature flag definition polls. Default: 30000.',\n )\n .optional(),\n disableGeoip: z\n .boolean()\n .describe('Disable GeoIP lookups globally. Useful for GDPR compliance.')\n .optional(),\n debug: z\n .boolean()\n .describe('Enable PostHog SDK debug logging. Default: false.')\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to an identity object. Keys: distinctId, $set, $set_once. Resolved on every push (server is stateless).',\n )\n .optional(),\n group: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to a group object. Keys: type, key, properties. Resolved on every push.',\n )\n .optional(),\n include: z\n .array(z.string())\n .describe(\n 'Event sections to flatten into capture() properties (e.g. [\"data\", \"globals\"]).',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n identify: z\n .unknown()\n .describe(\n 'Per-event identity mapping. Resolves to { distinctId, $set?, $set_once? }. Fires client.identify() when $set/$set_once present.',\n )\n .optional(),\n group: z\n .unknown()\n .describe(\n 'Group assignment. Resolves to { type, key, properties? }. Fires client.groupIdentify() when properties present, adds groups to capture().',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env } from '../types';\n\n/**\n * Mock PostHog class that records method calls for testing.\n * Follows the BigQuery env.BigQuery constructor injection pattern.\n */\nfunction createMockPostHog() {\n return class MockPostHog {\n apiKey: string;\n options: Record<string, unknown>;\n calls: Array<{ method: string; args: unknown[] }>;\n\n constructor(apiKey: string, options?: Record<string, unknown>) {\n this.apiKey = apiKey;\n this.options = options || {};\n this.calls = [];\n }\n\n capture(params: Record<string, unknown>) {\n this.calls.push({ method: 'capture', args: [params] });\n }\n\n identify(params: Record<string, unknown>) {\n this.calls.push({ method: 'identify', args: [params] });\n }\n\n groupIdentify(params: Record<string, unknown>) {\n this.calls.push({ method: 'groupIdentify', args: [params] });\n }\n\n flush() {\n this.calls.push({ method: 'flush', args: [] });\n return Promise.resolve();\n }\n\n async shutdown() {\n this.calls.push({ method: 'shutdown', args: [] });\n }\n\n enable() {\n this.calls.push({ method: 'enable', args: [] });\n }\n\n disable() {\n this.calls.push({ method: 'disable', args: [] });\n }\n };\n}\n\n/**\n * Standard mock environment for push operations.\n * Injects a mock PostHog class constructor via env.PostHog.\n */\nexport const push: Env = {\n get PostHog() {\n return createMockPostHog() as unknown as Env['PostHog'];\n },\n};\n\n/** Simulation tracking paths for CLI --simulate. */\nexport const simulation = [\n 'call:client.capture',\n 'call:client.identify',\n 'call:client.groupIdentify',\n 'call:client.shutdown',\n];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * PostHog server step examples carry destination-level settings and\n * optional configInclude for the test runner to wire up.\n *\n * At push time the destination invokes methods on a `client` constructed\n * via `env.PostHog`. Each `out` tuple is `['client.<method>', ...args]`\n * matching the underlying SDK signature. Multiple calls (identify +\n * capture, groupIdentify + capture) are expressed as a tuple list.\n */\nexport type PostHogStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n configInclude?: string[];\n /** Consent granted before `in` so a gated destination is loaded first. */\n before?: WalkerOS.Consent;\n};\n\n/**\n * Default event forwarding - every walkerOS event becomes\n * client.capture({ distinctId, event, properties }). With no mapping\n * and no include, properties is {}. distinctId falls back to event.user.id.\n */\nexport const defaultCapture: PostHogStepExample = {\n title: 'Default capture',\n description:\n 'A walker event becomes a PostHog capture call with the user id as distinctId and no extra properties.',\n in: getEvent('product view', { timestamp: 1700000100 }),\n out: [\n [\n 'client.capture',\n {\n distinctId: 'us3r',\n event: 'product view',\n properties: {},\n },\n ],\n ],\n};\n\n/**\n * Capture with include - destination-level include flattens data and\n * globals sections into prefixed properties.\n */\nexport const captureWithInclude: PostHogStepExample = {\n title: 'Capture with include',\n description:\n 'Destination-level include flattens data and globals sections into prefixed PostHog event properties.',\n in: getEvent('order complete', { timestamp: 1700000101 }),\n configInclude: ['data', 'globals'],\n out: [\n [\n 'client.capture',\n {\n distinctId: 'us3r',\n event: 'order complete',\n properties: {\n data_id: '0rd3r1d',\n data_currency: 'EUR',\n data_shipping: 5.22,\n data_taxes: 73.76,\n data_total: 555,\n globals_pagegroup: 'shop',\n },\n },\n ],\n ],\n};\n\n/**\n * Identify with $set and $set_once - per-event mapping fires\n * client.identify() with person properties. silent: true suppresses capture.\n */\nexport const identifyWithSetAndSetOnce: PostHogStepExample = {\n title: 'Identify with $set',\n description:\n 'A user login fires PostHog identify with $set and $set_once person properties and skips the capture.',\n in: getEvent('user login', {\n timestamp: 1700000102,\n data: {\n user_id: 'new-user-123',\n email: 'user@acme.com',\n plan: 'premium',\n },\n }),\n mapping: {\n silent: true,\n settings: {\n identify: {\n map: {\n distinctId: 'data.user_id',\n $set: {\n map: {\n email: 'data.email',\n plan: 'data.plan',\n },\n },\n $set_once: {\n map: {\n first_login: 'timestamp',\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'client.identify',\n {\n distinctId: 'new-user-123',\n properties: {\n $set: {\n email: 'user@acme.com',\n plan: 'premium',\n },\n $set_once: {\n first_login: 1700000102,\n },\n },\n },\n ],\n ],\n};\n\n/**\n * Group identify with properties - per-event mapping fires\n * client.groupIdentify() with group properties. silent: true suppresses capture.\n */\nexport const groupIdentifyWithProperties: PostHogStepExample = {\n title: 'Group identify',\n description:\n 'A company update fires PostHog groupIdentify with group type, key, and associated group properties.',\n in: getEvent('company update', {\n timestamp: 1700000103,\n data: {\n company_id: 'company_123',\n company_name: 'Acme',\n plan: 'enterprise',\n },\n }),\n mapping: {\n silent: true,\n settings: {\n group: {\n map: {\n type: { value: 'company' },\n key: 'data.company_id',\n properties: {\n map: {\n name: 'data.company_name',\n plan: 'data.plan',\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'client.groupIdentify',\n {\n groupType: 'company',\n groupKey: 'company_123',\n properties: {\n name: 'Acme',\n plan: 'enterprise',\n },\n },\n ],\n ],\n};\n\n/**\n * Capture with group context - destination-level settings.group resolves\n * type + key (no properties). The capture call includes groups.\n */\nexport const captureWithGroupContext: PostHogStepExample = {\n title: 'Capture with group',\n description:\n 'A destination-level group mapping attaches the resolved group context to every PostHog capture call.',\n in: getEvent('page view', {\n timestamp: 1700000104,\n globals: { pagegroup: 'docs', company_id: 'company_123' },\n }),\n settings: {\n group: {\n map: {\n type: { value: 'company' },\n key: 'globals.company_id',\n },\n },\n },\n out: [\n [\n 'client.capture',\n {\n distinctId: 'us3r',\n event: 'page view',\n properties: {},\n groups: { company: 'company_123' },\n },\n ],\n ],\n};\n\n/**\n * Consent revoked - after analytics consent is granted (PostHog loads and is\n * enabled), revoking it calls client.disable() via the on('consent') handler.\n * The destination is never loaded under denied consent, so the disable is a\n * real revocation of an already-granted destination.\n */\nexport const consentRevoke: PostHogStepExample = {\n title: 'Consent revoked',\n description:\n 'A walker consent command with analytics denied calls client.disable on the PostHog client.',\n command: 'consent',\n before: { analytics: true },\n in: { analytics: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['client.enable'], ['client.disable']],\n};\n\n/**\n * Consent granted - client.enable() is called.\n */\nexport const consentGrant: PostHogStepExample = {\n title: 'Consent granted',\n description:\n 'A walker consent command with analytics granted calls client.enable on the PostHog client.',\n command: 'consent',\n in: { analytics: true } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['client.enable']],\n};\n"],"mappings":"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","names":["import_dev","import_dev"]}
1
+ {"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z.object({\n apiKey: z\n .string()\n .min(1)\n .describe(\n 'PostHog project API key (starts with \"phc_\"). Find it in PostHog project settings.',\n ),\n host: z\n .string()\n .describe(\n 'PostHog API host. Defaults to https://us.i.posthog.com. Use https://eu.i.posthog.com for EU or your self-hosted URL.',\n )\n .optional(),\n flushAt: z\n .number()\n .describe('Number of events queued before auto-flush. Default: 20.')\n .optional(),\n flushInterval: z\n .number()\n .describe('Milliseconds between periodic flushes. Default: 10000.')\n .optional(),\n personalApiKey: z\n .string()\n .describe('Personal API key (phx_...) for local feature flag evaluation.')\n .optional(),\n featureFlagsPollingInterval: z\n .number()\n .describe(\n 'Milliseconds between feature flag definition polls. Default: 30000.',\n )\n .optional(),\n disableGeoip: z\n .boolean()\n .describe('Disable GeoIP lookups globally. Useful for GDPR compliance.')\n .optional(),\n debug: z\n .boolean()\n .describe('Enable PostHog SDK debug logging. Default: false.')\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to an identity object. Keys: distinctId, $set, $set_once. Resolved on every push (server is stateless).',\n )\n .optional(),\n group: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to a group object. Keys: type, key, properties. Resolved on every push.',\n )\n .optional(),\n include: z\n .array(z.string())\n .describe(\n 'Event sections to flatten into capture() properties (e.g. [\"data\", \"globals\"]).',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n identify: z\n .unknown()\n .describe(\n 'Per-event identity mapping. Resolves to { distinctId, $set?, $set_once? }. Fires client.identify() when $set/$set_once present.',\n )\n .optional(),\n group: z\n .unknown()\n .describe(\n 'Group assignment. Resolves to { type, key, properties? }. Fires client.groupIdentify() when properties present, adds groups to capture().',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env } from '../types';\n\n/**\n * Mock PostHog class that records method calls for testing.\n * Follows the BigQuery env.BigQuery constructor injection pattern.\n */\nfunction createMockPostHog() {\n return class MockPostHog {\n apiKey: string;\n options: Record<string, unknown>;\n calls: Array<{ method: string; args: unknown[] }>;\n\n constructor(apiKey: string, options?: Record<string, unknown>) {\n this.apiKey = apiKey;\n this.options = options || {};\n this.calls = [];\n }\n\n capture(params: Record<string, unknown>) {\n this.calls.push({ method: 'capture', args: [params] });\n }\n\n identify(params: Record<string, unknown>) {\n this.calls.push({ method: 'identify', args: [params] });\n }\n\n groupIdentify(params: Record<string, unknown>) {\n this.calls.push({ method: 'groupIdentify', args: [params] });\n }\n\n flush() {\n this.calls.push({ method: 'flush', args: [] });\n return Promise.resolve();\n }\n\n async shutdown() {\n this.calls.push({ method: 'shutdown', args: [] });\n }\n\n enable() {\n this.calls.push({ method: 'enable', args: [] });\n }\n\n disable() {\n this.calls.push({ method: 'disable', args: [] });\n }\n };\n}\n\n/**\n * Standard mock environment for push operations.\n * Injects a mock PostHog class constructor via env.PostHog.\n */\nexport const push: Env = {\n get PostHog() {\n return createMockPostHog();\n },\n};\n\n/** Simulation tracking paths for CLI --simulate. */\nexport const simulation = [\n 'call:PostHog.capture',\n 'call:PostHog.identify',\n 'call:PostHog.groupIdentify',\n 'call:PostHog.shutdown',\n];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * PostHog server step examples carry destination-level settings and\n * optional configInclude for the test runner to wire up.\n *\n * At push time the destination invokes methods on a `client` constructed\n * via `env.PostHog`. Each `out` tuple is `['client.<method>', ...args]`\n * matching the underlying SDK signature. Multiple calls (identify +\n * capture, groupIdentify + capture) are expressed as a tuple list.\n */\nexport type PostHogStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n configInclude?: string[];\n /** Consent granted before `in` so a gated destination is loaded first. */\n before?: WalkerOS.Consent;\n};\n\n/**\n * Default event forwarding - every walkerOS event becomes\n * client.capture({ distinctId, event, properties }). With no mapping\n * and no include, properties is {}. distinctId falls back to event.user.id.\n */\nexport const defaultCapture: PostHogStepExample = {\n title: 'Default capture',\n description:\n 'A walker event becomes a PostHog capture call with the user id as distinctId and no extra properties.',\n in: getEvent('product view', { timestamp: 1700000100 }),\n out: [\n [\n 'client.capture',\n {\n distinctId: 'us3r',\n event: 'product view',\n properties: {},\n },\n ],\n ],\n};\n\n/**\n * Capture with include - destination-level include flattens data and\n * globals sections into prefixed properties.\n */\nexport const captureWithInclude: PostHogStepExample = {\n title: 'Capture with include',\n description:\n 'Destination-level include flattens data and globals sections into prefixed PostHog event properties.',\n in: getEvent('order complete', { timestamp: 1700000101 }),\n configInclude: ['data', 'globals'],\n out: [\n [\n 'client.capture',\n {\n distinctId: 'us3r',\n event: 'order complete',\n properties: {\n data_id: '0rd3r1d',\n data_currency: 'EUR',\n data_shipping: 5.22,\n data_taxes: 73.76,\n data_total: 555,\n globals_pagegroup: 'shop',\n },\n },\n ],\n ],\n};\n\n/**\n * Identify with $set and $set_once - per-event mapping fires\n * client.identify() with person properties. silent: true suppresses capture.\n */\nexport const identifyWithSetAndSetOnce: PostHogStepExample = {\n title: 'Identify with $set',\n description:\n 'A user login fires PostHog identify with $set and $set_once person properties and skips the capture.',\n in: getEvent('user login', {\n timestamp: 1700000102,\n data: {\n user_id: 'new-user-123',\n email: 'user@acme.com',\n plan: 'premium',\n },\n }),\n mapping: {\n silent: true,\n settings: {\n identify: {\n map: {\n distinctId: 'data.user_id',\n $set: {\n map: {\n email: 'data.email',\n plan: 'data.plan',\n },\n },\n $set_once: {\n map: {\n first_login: 'timestamp',\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'client.identify',\n {\n distinctId: 'new-user-123',\n properties: {\n $set: {\n email: 'user@acme.com',\n plan: 'premium',\n },\n $set_once: {\n first_login: 1700000102,\n },\n },\n },\n ],\n ],\n};\n\n/**\n * Group identify with properties - per-event mapping fires\n * client.groupIdentify() with group properties. silent: true suppresses capture.\n */\nexport const groupIdentifyWithProperties: PostHogStepExample = {\n title: 'Group identify',\n description:\n 'A company update fires PostHog groupIdentify with group type, key, and associated group properties.',\n in: getEvent('company update', {\n timestamp: 1700000103,\n data: {\n company_id: 'company_123',\n company_name: 'Acme',\n plan: 'enterprise',\n },\n }),\n mapping: {\n silent: true,\n settings: {\n group: {\n map: {\n type: { value: 'company' },\n key: 'data.company_id',\n properties: {\n map: {\n name: 'data.company_name',\n plan: 'data.plan',\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'client.groupIdentify',\n {\n groupType: 'company',\n groupKey: 'company_123',\n properties: {\n name: 'Acme',\n plan: 'enterprise',\n },\n },\n ],\n ],\n};\n\n/**\n * Capture with group context - destination-level settings.group resolves\n * type + key (no properties). The capture call includes groups.\n */\nexport const captureWithGroupContext: PostHogStepExample = {\n title: 'Capture with group',\n description:\n 'A destination-level group mapping attaches the resolved group context to every PostHog capture call.',\n in: getEvent('page view', {\n timestamp: 1700000104,\n globals: { pagegroup: 'docs', company_id: 'company_123' },\n }),\n settings: {\n group: {\n map: {\n type: { value: 'company' },\n key: 'globals.company_id',\n },\n },\n },\n out: [\n [\n 'client.capture',\n {\n distinctId: 'us3r',\n event: 'page view',\n properties: {},\n groups: { company: 'company_123' },\n },\n ],\n ],\n};\n\n/**\n * Consent revoked - after analytics consent is granted (PostHog loads and is\n * enabled), revoking it calls client.disable() via the on('consent') handler.\n * The destination is never loaded under denied consent, so the disable is a\n * real revocation of an already-granted destination.\n */\nexport const consentRevoke: PostHogStepExample = {\n title: 'Consent revoked',\n description:\n 'A walker consent command with analytics denied calls client.disable on the PostHog client.',\n command: 'consent',\n before: { analytics: true },\n in: { analytics: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['client.enable'], ['client.disable']],\n};\n\n/**\n * Consent granted - client.enable() is called.\n */\nexport const consentGrant: PostHogStepExample = {\n title: 'Consent granted',\n description:\n 'A walker consent command with analytics granted calls client.enable on the PostHog client.',\n command: 'consent',\n in: { analytics: true } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['client.enable']],\n};\n"],"mappings":"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","names":["import_dev","import_dev"]}
package/dist/dev.mjs CHANGED
@@ -1 +1 @@
1
- var e=Object.defineProperty,t=(t,i)=>{for(var o in i)e(t,o,{get:i[o],enumerable:!0})},i={};t(i,{MappingSchema:()=>r,SettingsSchema:()=>n,mapping:()=>l,settings:()=>p});import{zodToSchema as o}from"@walkeros/core/dev";import{z as s}from"@walkeros/core/dev";var n=s.object({apiKey:s.string().min(1).describe('PostHog project API key (starts with "phc_"). Find it in PostHog project settings.'),host:s.string().describe("PostHog API host. Defaults to https://us.i.posthog.com. Use https://eu.i.posthog.com for EU or your self-hosted URL.").optional(),flushAt:s.number().describe("Number of events queued before auto-flush. Default: 20.").optional(),flushInterval:s.number().describe("Milliseconds between periodic flushes. Default: 10000.").optional(),personalApiKey:s.string().describe("Personal API key (phx_...) for local feature flag evaluation.").optional(),featureFlagsPollingInterval:s.number().describe("Milliseconds between feature flag definition polls. Default: 30000.").optional(),disableGeoip:s.boolean().describe("Disable GeoIP lookups globally. Useful for GDPR compliance.").optional(),debug:s.boolean().describe("Enable PostHog SDK debug logging. Default: false.").optional(),identify:s.unknown().describe("walkerOS mapping value resolving to an identity object. Keys: distinctId, $set, $set_once. Resolved on every push (server is stateless).").optional(),group:s.unknown().describe("walkerOS mapping value resolving to a group object. Keys: type, key, properties. Resolved on every push.").optional(),include:s.array(s.string()).describe('Event sections to flatten into capture() properties (e.g. ["data", "globals"]).').optional()});import{z as a}from"@walkeros/core/dev";var r=a.object({identify:a.unknown().describe("Per-event identity mapping. Resolves to { distinctId, $set?, $set_once? }. Fires client.identify() when $set/$set_once present.").optional(),group:a.unknown().describe("Group assignment. Resolves to { type, key, properties? }. Fires client.groupIdentify() when properties present, adds groups to capture().").optional()}),p=o(n),l=o(r),c={};t(c,{env:()=>d,step:()=>g});var d={};t(d,{push:()=>u,simulation:()=>m});var u={get PostHog(){return class{apiKey;options;calls;constructor(e,t){this.apiKey=e,this.options=t||{},this.calls=[]}capture(e){this.calls.push({method:"capture",args:[e]})}identify(e){this.calls.push({method:"identify",args:[e]})}groupIdentify(e){this.calls.push({method:"groupIdentify",args:[e]})}flush(){return this.calls.push({method:"flush",args:[]}),Promise.resolve()}async shutdown(){this.calls.push({method:"shutdown",args:[]})}enable(){this.calls.push({method:"enable",args:[]})}disable(){this.calls.push({method:"disable",args:[]})}}}},m=["call:client.capture","call:client.identify","call:client.groupIdentify","call:client.shutdown"],g={};t(g,{captureWithGroupContext:()=>w,captureWithInclude:()=>f,consentGrant:()=>k,consentRevoke:()=>_,defaultCapture:()=>y,groupIdentifyWithProperties:()=>v,identifyWithSetAndSetOnce:()=>b});import{getEvent as h}from"@walkeros/core";var y={title:"Default capture",description:"A walker event becomes a PostHog capture call with the user id as distinctId and no extra properties.",in:h("product view",{timestamp:1700000100}),out:[["client.capture",{distinctId:"us3r",event:"product view",properties:{}}]]},f={title:"Capture with include",description:"Destination-level include flattens data and globals sections into prefixed PostHog event properties.",in:h("order complete",{timestamp:1700000101}),configInclude:["data","globals"],out:[["client.capture",{distinctId:"us3r",event:"order complete",properties:{data_id:"0rd3r1d",data_currency:"EUR",data_shipping:5.22,data_taxes:73.76,data_total:555,globals_pagegroup:"shop"}}]]},b={title:"Identify with $set",description:"A user login fires PostHog identify with $set and $set_once person properties and skips the capture.",in:h("user login",{timestamp:1700000102,data:{user_id:"new-user-123",email:"user@acme.com",plan:"premium"}}),mapping:{silent:!0,settings:{identify:{map:{distinctId:"data.user_id",$set:{map:{email:"data.email",plan:"data.plan"}},$set_once:{map:{first_login:"timestamp"}}}}}},out:[["client.identify",{distinctId:"new-user-123",properties:{$set:{email:"user@acme.com",plan:"premium"},$set_once:{first_login:1700000102}}}]]},v={title:"Group identify",description:"A company update fires PostHog groupIdentify with group type, key, and associated group properties.",in:h("company update",{timestamp:1700000103,data:{company_id:"company_123",company_name:"Acme",plan:"enterprise"}}),mapping:{silent:!0,settings:{group:{map:{type:{value:"company"},key:"data.company_id",properties:{map:{name:"data.company_name",plan:"data.plan"}}}}}},out:[["client.groupIdentify",{groupType:"company",groupKey:"company_123",properties:{name:"Acme",plan:"enterprise"}}]]},w={title:"Capture with group",description:"A destination-level group mapping attaches the resolved group context to every PostHog capture call.",in:h("page view",{timestamp:1700000104,globals:{pagegroup:"docs",company_id:"company_123"}}),settings:{group:{map:{type:{value:"company"},key:"globals.company_id"}}},out:[["client.capture",{distinctId:"us3r",event:"page view",properties:{},groups:{company:"company_123"}}]]},_={title:"Consent revoked",description:"A walker consent command with analytics denied calls client.disable on the PostHog client.",command:"consent",before:{analytics:!0},in:{analytics:!1},settings:{},out:[["client.enable"],["client.disable"]]},k={title:"Consent granted",description:"A walker consent command with analytics granted calls client.enable on the PostHog client.",command:"consent",in:{analytics:!0},settings:{},out:[["client.enable"]]};export{c as examples,i as schemas};//# sourceMappingURL=dev.mjs.map
1
+ var e=Object.defineProperty,t=(t,o)=>{for(var i in o)e(t,i,{get:o[i],enumerable:!0})},o={};t(o,{MappingSchema:()=>r,SettingsSchema:()=>a,mapping:()=>l,settings:()=>p});import{zodToSchema as i}from"@walkeros/core/dev";import{z as s}from"@walkeros/core/dev";var a=s.object({apiKey:s.string().min(1).describe('PostHog project API key (starts with "phc_"). Find it in PostHog project settings.'),host:s.string().describe("PostHog API host. Defaults to https://us.i.posthog.com. Use https://eu.i.posthog.com for EU or your self-hosted URL.").optional(),flushAt:s.number().describe("Number of events queued before auto-flush. Default: 20.").optional(),flushInterval:s.number().describe("Milliseconds between periodic flushes. Default: 10000.").optional(),personalApiKey:s.string().describe("Personal API key (phx_...) for local feature flag evaluation.").optional(),featureFlagsPollingInterval:s.number().describe("Milliseconds between feature flag definition polls. Default: 30000.").optional(),disableGeoip:s.boolean().describe("Disable GeoIP lookups globally. Useful for GDPR compliance.").optional(),debug:s.boolean().describe("Enable PostHog SDK debug logging. Default: false.").optional(),identify:s.unknown().describe("walkerOS mapping value resolving to an identity object. Keys: distinctId, $set, $set_once. Resolved on every push (server is stateless).").optional(),group:s.unknown().describe("walkerOS mapping value resolving to a group object. Keys: type, key, properties. Resolved on every push.").optional(),include:s.array(s.string()).describe('Event sections to flatten into capture() properties (e.g. ["data", "globals"]).').optional()});import{z as n}from"@walkeros/core/dev";var r=n.object({identify:n.unknown().describe("Per-event identity mapping. Resolves to { distinctId, $set?, $set_once? }. Fires client.identify() when $set/$set_once present.").optional(),group:n.unknown().describe("Group assignment. Resolves to { type, key, properties? }. Fires client.groupIdentify() when properties present, adds groups to capture().").optional()}),p=i(a),l=i(r),c={};t(c,{env:()=>d,step:()=>m});var d={};t(d,{push:()=>u,simulation:()=>g});var u={get PostHog(){return class{apiKey;options;calls;constructor(e,t){this.apiKey=e,this.options=t||{},this.calls=[]}capture(e){this.calls.push({method:"capture",args:[e]})}identify(e){this.calls.push({method:"identify",args:[e]})}groupIdentify(e){this.calls.push({method:"groupIdentify",args:[e]})}flush(){return this.calls.push({method:"flush",args:[]}),Promise.resolve()}async shutdown(){this.calls.push({method:"shutdown",args:[]})}enable(){this.calls.push({method:"enable",args:[]})}disable(){this.calls.push({method:"disable",args:[]})}}}},g=["call:PostHog.capture","call:PostHog.identify","call:PostHog.groupIdentify","call:PostHog.shutdown"],m={};t(m,{captureWithGroupContext:()=>w,captureWithInclude:()=>f,consentGrant:()=>P,consentRevoke:()=>_,defaultCapture:()=>y,groupIdentifyWithProperties:()=>v,identifyWithSetAndSetOnce:()=>b});import{getEvent as h}from"@walkeros/core";var y={title:"Default capture",description:"A walker event becomes a PostHog capture call with the user id as distinctId and no extra properties.",in:h("product view",{timestamp:1700000100}),out:[["client.capture",{distinctId:"us3r",event:"product view",properties:{}}]]},f={title:"Capture with include",description:"Destination-level include flattens data and globals sections into prefixed PostHog event properties.",in:h("order complete",{timestamp:1700000101}),configInclude:["data","globals"],out:[["client.capture",{distinctId:"us3r",event:"order complete",properties:{data_id:"0rd3r1d",data_currency:"EUR",data_shipping:5.22,data_taxes:73.76,data_total:555,globals_pagegroup:"shop"}}]]},b={title:"Identify with $set",description:"A user login fires PostHog identify with $set and $set_once person properties and skips the capture.",in:h("user login",{timestamp:1700000102,data:{user_id:"new-user-123",email:"user@acme.com",plan:"premium"}}),mapping:{silent:!0,settings:{identify:{map:{distinctId:"data.user_id",$set:{map:{email:"data.email",plan:"data.plan"}},$set_once:{map:{first_login:"timestamp"}}}}}},out:[["client.identify",{distinctId:"new-user-123",properties:{$set:{email:"user@acme.com",plan:"premium"},$set_once:{first_login:1700000102}}}]]},v={title:"Group identify",description:"A company update fires PostHog groupIdentify with group type, key, and associated group properties.",in:h("company update",{timestamp:1700000103,data:{company_id:"company_123",company_name:"Acme",plan:"enterprise"}}),mapping:{silent:!0,settings:{group:{map:{type:{value:"company"},key:"data.company_id",properties:{map:{name:"data.company_name",plan:"data.plan"}}}}}},out:[["client.groupIdentify",{groupType:"company",groupKey:"company_123",properties:{name:"Acme",plan:"enterprise"}}]]},w={title:"Capture with group",description:"A destination-level group mapping attaches the resolved group context to every PostHog capture call.",in:h("page view",{timestamp:1700000104,globals:{pagegroup:"docs",company_id:"company_123"}}),settings:{group:{map:{type:{value:"company"},key:"globals.company_id"}}},out:[["client.capture",{distinctId:"us3r",event:"page view",properties:{},groups:{company:"company_123"}}]]},_={title:"Consent revoked",description:"A walker consent command with analytics denied calls client.disable on the PostHog client.",command:"consent",before:{analytics:!0},in:{analytics:!1},settings:{},out:[["client.enable"],["client.disable"]]},P={title:"Consent granted",description:"A walker consent command with analytics granted calls client.enable on the PostHog client.",command:"consent",in:{analytics:!0},settings:{},out:[["client.enable"]]};export{c as examples,o as schemas};//# sourceMappingURL=dev.mjs.map
package/dist/dev.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z.object({\n apiKey: z\n .string()\n .min(1)\n .describe(\n 'PostHog project API key (starts with \"phc_\"). Find it in PostHog project settings.',\n ),\n host: z\n .string()\n .describe(\n 'PostHog API host. Defaults to https://us.i.posthog.com. Use https://eu.i.posthog.com for EU or your self-hosted URL.',\n )\n .optional(),\n flushAt: z\n .number()\n .describe('Number of events queued before auto-flush. Default: 20.')\n .optional(),\n flushInterval: z\n .number()\n .describe('Milliseconds between periodic flushes. Default: 10000.')\n .optional(),\n personalApiKey: z\n .string()\n .describe('Personal API key (phx_...) for local feature flag evaluation.')\n .optional(),\n featureFlagsPollingInterval: z\n .number()\n .describe(\n 'Milliseconds between feature flag definition polls. Default: 30000.',\n )\n .optional(),\n disableGeoip: z\n .boolean()\n .describe('Disable GeoIP lookups globally. Useful for GDPR compliance.')\n .optional(),\n debug: z\n .boolean()\n .describe('Enable PostHog SDK debug logging. Default: false.')\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to an identity object. Keys: distinctId, $set, $set_once. Resolved on every push (server is stateless).',\n )\n .optional(),\n group: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to a group object. Keys: type, key, properties. Resolved on every push.',\n )\n .optional(),\n include: z\n .array(z.string())\n .describe(\n 'Event sections to flatten into capture() properties (e.g. [\"data\", \"globals\"]).',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n identify: z\n .unknown()\n .describe(\n 'Per-event identity mapping. Resolves to { distinctId, $set?, $set_once? }. Fires client.identify() when $set/$set_once present.',\n )\n .optional(),\n group: z\n .unknown()\n .describe(\n 'Group assignment. Resolves to { type, key, properties? }. Fires client.groupIdentify() when properties present, adds groups to capture().',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env } from '../types';\n\n/**\n * Mock PostHog class that records method calls for testing.\n * Follows the BigQuery env.BigQuery constructor injection pattern.\n */\nfunction createMockPostHog() {\n return class MockPostHog {\n apiKey: string;\n options: Record<string, unknown>;\n calls: Array<{ method: string; args: unknown[] }>;\n\n constructor(apiKey: string, options?: Record<string, unknown>) {\n this.apiKey = apiKey;\n this.options = options || {};\n this.calls = [];\n }\n\n capture(params: Record<string, unknown>) {\n this.calls.push({ method: 'capture', args: [params] });\n }\n\n identify(params: Record<string, unknown>) {\n this.calls.push({ method: 'identify', args: [params] });\n }\n\n groupIdentify(params: Record<string, unknown>) {\n this.calls.push({ method: 'groupIdentify', args: [params] });\n }\n\n flush() {\n this.calls.push({ method: 'flush', args: [] });\n return Promise.resolve();\n }\n\n async shutdown() {\n this.calls.push({ method: 'shutdown', args: [] });\n }\n\n enable() {\n this.calls.push({ method: 'enable', args: [] });\n }\n\n disable() {\n this.calls.push({ method: 'disable', args: [] });\n }\n };\n}\n\n/**\n * Standard mock environment for push operations.\n * Injects a mock PostHog class constructor via env.PostHog.\n */\nexport const push: Env = {\n get PostHog() {\n return createMockPostHog() as unknown as Env['PostHog'];\n },\n};\n\n/** Simulation tracking paths for CLI --simulate. */\nexport const simulation = [\n 'call:client.capture',\n 'call:client.identify',\n 'call:client.groupIdentify',\n 'call:client.shutdown',\n];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * PostHog server step examples carry destination-level settings and\n * optional configInclude for the test runner to wire up.\n *\n * At push time the destination invokes methods on a `client` constructed\n * via `env.PostHog`. Each `out` tuple is `['client.<method>', ...args]`\n * matching the underlying SDK signature. Multiple calls (identify +\n * capture, groupIdentify + capture) are expressed as a tuple list.\n */\nexport type PostHogStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n configInclude?: string[];\n /** Consent granted before `in` so a gated destination is loaded first. */\n before?: WalkerOS.Consent;\n};\n\n/**\n * Default event forwarding - every walkerOS event becomes\n * client.capture({ distinctId, event, properties }). With no mapping\n * and no include, properties is {}. distinctId falls back to event.user.id.\n */\nexport const defaultCapture: PostHogStepExample = {\n title: 'Default capture',\n description:\n 'A walker event becomes a PostHog capture call with the user id as distinctId and no extra properties.',\n in: getEvent('product view', { timestamp: 1700000100 }),\n out: [\n [\n 'client.capture',\n {\n distinctId: 'us3r',\n event: 'product view',\n properties: {},\n },\n ],\n ],\n};\n\n/**\n * Capture with include - destination-level include flattens data and\n * globals sections into prefixed properties.\n */\nexport const captureWithInclude: PostHogStepExample = {\n title: 'Capture with include',\n description:\n 'Destination-level include flattens data and globals sections into prefixed PostHog event properties.',\n in: getEvent('order complete', { timestamp: 1700000101 }),\n configInclude: ['data', 'globals'],\n out: [\n [\n 'client.capture',\n {\n distinctId: 'us3r',\n event: 'order complete',\n properties: {\n data_id: '0rd3r1d',\n data_currency: 'EUR',\n data_shipping: 5.22,\n data_taxes: 73.76,\n data_total: 555,\n globals_pagegroup: 'shop',\n },\n },\n ],\n ],\n};\n\n/**\n * Identify with $set and $set_once - per-event mapping fires\n * client.identify() with person properties. silent: true suppresses capture.\n */\nexport const identifyWithSetAndSetOnce: PostHogStepExample = {\n title: 'Identify with $set',\n description:\n 'A user login fires PostHog identify with $set and $set_once person properties and skips the capture.',\n in: getEvent('user login', {\n timestamp: 1700000102,\n data: {\n user_id: 'new-user-123',\n email: 'user@acme.com',\n plan: 'premium',\n },\n }),\n mapping: {\n silent: true,\n settings: {\n identify: {\n map: {\n distinctId: 'data.user_id',\n $set: {\n map: {\n email: 'data.email',\n plan: 'data.plan',\n },\n },\n $set_once: {\n map: {\n first_login: 'timestamp',\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'client.identify',\n {\n distinctId: 'new-user-123',\n properties: {\n $set: {\n email: 'user@acme.com',\n plan: 'premium',\n },\n $set_once: {\n first_login: 1700000102,\n },\n },\n },\n ],\n ],\n};\n\n/**\n * Group identify with properties - per-event mapping fires\n * client.groupIdentify() with group properties. silent: true suppresses capture.\n */\nexport const groupIdentifyWithProperties: PostHogStepExample = {\n title: 'Group identify',\n description:\n 'A company update fires PostHog groupIdentify with group type, key, and associated group properties.',\n in: getEvent('company update', {\n timestamp: 1700000103,\n data: {\n company_id: 'company_123',\n company_name: 'Acme',\n plan: 'enterprise',\n },\n }),\n mapping: {\n silent: true,\n settings: {\n group: {\n map: {\n type: { value: 'company' },\n key: 'data.company_id',\n properties: {\n map: {\n name: 'data.company_name',\n plan: 'data.plan',\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'client.groupIdentify',\n {\n groupType: 'company',\n groupKey: 'company_123',\n properties: {\n name: 'Acme',\n plan: 'enterprise',\n },\n },\n ],\n ],\n};\n\n/**\n * Capture with group context - destination-level settings.group resolves\n * type + key (no properties). The capture call includes groups.\n */\nexport const captureWithGroupContext: PostHogStepExample = {\n title: 'Capture with group',\n description:\n 'A destination-level group mapping attaches the resolved group context to every PostHog capture call.',\n in: getEvent('page view', {\n timestamp: 1700000104,\n globals: { pagegroup: 'docs', company_id: 'company_123' },\n }),\n settings: {\n group: {\n map: {\n type: { value: 'company' },\n key: 'globals.company_id',\n },\n },\n },\n out: [\n [\n 'client.capture',\n {\n distinctId: 'us3r',\n event: 'page view',\n properties: {},\n groups: { company: 'company_123' },\n },\n ],\n ],\n};\n\n/**\n * Consent revoked - after analytics consent is granted (PostHog loads and is\n * enabled), revoking it calls client.disable() via the on('consent') handler.\n * The destination is never loaded under denied consent, so the disable is a\n * real revocation of an already-granted destination.\n */\nexport const consentRevoke: PostHogStepExample = {\n title: 'Consent revoked',\n description:\n 'A walker consent command with analytics denied calls client.disable on the PostHog client.',\n command: 'consent',\n before: { analytics: true },\n in: { analytics: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['client.enable'], ['client.disable']],\n};\n\n/**\n * Consent granted - client.enable() is called.\n */\nexport const consentGrant: PostHogStepExample = {\n title: 'Consent granted',\n description:\n 'A walker consent command with analytics granted calls client.enable on the PostHog client.',\n command: 'consent',\n in: { analytics: true } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['client.enable']],\n};\n"],"mappings":"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","names":["z"]}
1
+ {"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z.object({\n apiKey: z\n .string()\n .min(1)\n .describe(\n 'PostHog project API key (starts with \"phc_\"). Find it in PostHog project settings.',\n ),\n host: z\n .string()\n .describe(\n 'PostHog API host. Defaults to https://us.i.posthog.com. Use https://eu.i.posthog.com for EU or your self-hosted URL.',\n )\n .optional(),\n flushAt: z\n .number()\n .describe('Number of events queued before auto-flush. Default: 20.')\n .optional(),\n flushInterval: z\n .number()\n .describe('Milliseconds between periodic flushes. Default: 10000.')\n .optional(),\n personalApiKey: z\n .string()\n .describe('Personal API key (phx_...) for local feature flag evaluation.')\n .optional(),\n featureFlagsPollingInterval: z\n .number()\n .describe(\n 'Milliseconds between feature flag definition polls. Default: 30000.',\n )\n .optional(),\n disableGeoip: z\n .boolean()\n .describe('Disable GeoIP lookups globally. Useful for GDPR compliance.')\n .optional(),\n debug: z\n .boolean()\n .describe('Enable PostHog SDK debug logging. Default: false.')\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to an identity object. Keys: distinctId, $set, $set_once. Resolved on every push (server is stateless).',\n )\n .optional(),\n group: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to a group object. Keys: type, key, properties. Resolved on every push.',\n )\n .optional(),\n include: z\n .array(z.string())\n .describe(\n 'Event sections to flatten into capture() properties (e.g. [\"data\", \"globals\"]).',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n identify: z\n .unknown()\n .describe(\n 'Per-event identity mapping. Resolves to { distinctId, $set?, $set_once? }. Fires client.identify() when $set/$set_once present.',\n )\n .optional(),\n group: z\n .unknown()\n .describe(\n 'Group assignment. Resolves to { type, key, properties? }. Fires client.groupIdentify() when properties present, adds groups to capture().',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env } from '../types';\n\n/**\n * Mock PostHog class that records method calls for testing.\n * Follows the BigQuery env.BigQuery constructor injection pattern.\n */\nfunction createMockPostHog() {\n return class MockPostHog {\n apiKey: string;\n options: Record<string, unknown>;\n calls: Array<{ method: string; args: unknown[] }>;\n\n constructor(apiKey: string, options?: Record<string, unknown>) {\n this.apiKey = apiKey;\n this.options = options || {};\n this.calls = [];\n }\n\n capture(params: Record<string, unknown>) {\n this.calls.push({ method: 'capture', args: [params] });\n }\n\n identify(params: Record<string, unknown>) {\n this.calls.push({ method: 'identify', args: [params] });\n }\n\n groupIdentify(params: Record<string, unknown>) {\n this.calls.push({ method: 'groupIdentify', args: [params] });\n }\n\n flush() {\n this.calls.push({ method: 'flush', args: [] });\n return Promise.resolve();\n }\n\n async shutdown() {\n this.calls.push({ method: 'shutdown', args: [] });\n }\n\n enable() {\n this.calls.push({ method: 'enable', args: [] });\n }\n\n disable() {\n this.calls.push({ method: 'disable', args: [] });\n }\n };\n}\n\n/**\n * Standard mock environment for push operations.\n * Injects a mock PostHog class constructor via env.PostHog.\n */\nexport const push: Env = {\n get PostHog() {\n return createMockPostHog();\n },\n};\n\n/** Simulation tracking paths for CLI --simulate. */\nexport const simulation = [\n 'call:PostHog.capture',\n 'call:PostHog.identify',\n 'call:PostHog.groupIdentify',\n 'call:PostHog.shutdown',\n];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * PostHog server step examples carry destination-level settings and\n * optional configInclude for the test runner to wire up.\n *\n * At push time the destination invokes methods on a `client` constructed\n * via `env.PostHog`. Each `out` tuple is `['client.<method>', ...args]`\n * matching the underlying SDK signature. Multiple calls (identify +\n * capture, groupIdentify + capture) are expressed as a tuple list.\n */\nexport type PostHogStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n configInclude?: string[];\n /** Consent granted before `in` so a gated destination is loaded first. */\n before?: WalkerOS.Consent;\n};\n\n/**\n * Default event forwarding - every walkerOS event becomes\n * client.capture({ distinctId, event, properties }). With no mapping\n * and no include, properties is {}. distinctId falls back to event.user.id.\n */\nexport const defaultCapture: PostHogStepExample = {\n title: 'Default capture',\n description:\n 'A walker event becomes a PostHog capture call with the user id as distinctId and no extra properties.',\n in: getEvent('product view', { timestamp: 1700000100 }),\n out: [\n [\n 'client.capture',\n {\n distinctId: 'us3r',\n event: 'product view',\n properties: {},\n },\n ],\n ],\n};\n\n/**\n * Capture with include - destination-level include flattens data and\n * globals sections into prefixed properties.\n */\nexport const captureWithInclude: PostHogStepExample = {\n title: 'Capture with include',\n description:\n 'Destination-level include flattens data and globals sections into prefixed PostHog event properties.',\n in: getEvent('order complete', { timestamp: 1700000101 }),\n configInclude: ['data', 'globals'],\n out: [\n [\n 'client.capture',\n {\n distinctId: 'us3r',\n event: 'order complete',\n properties: {\n data_id: '0rd3r1d',\n data_currency: 'EUR',\n data_shipping: 5.22,\n data_taxes: 73.76,\n data_total: 555,\n globals_pagegroup: 'shop',\n },\n },\n ],\n ],\n};\n\n/**\n * Identify with $set and $set_once - per-event mapping fires\n * client.identify() with person properties. silent: true suppresses capture.\n */\nexport const identifyWithSetAndSetOnce: PostHogStepExample = {\n title: 'Identify with $set',\n description:\n 'A user login fires PostHog identify with $set and $set_once person properties and skips the capture.',\n in: getEvent('user login', {\n timestamp: 1700000102,\n data: {\n user_id: 'new-user-123',\n email: 'user@acme.com',\n plan: 'premium',\n },\n }),\n mapping: {\n silent: true,\n settings: {\n identify: {\n map: {\n distinctId: 'data.user_id',\n $set: {\n map: {\n email: 'data.email',\n plan: 'data.plan',\n },\n },\n $set_once: {\n map: {\n first_login: 'timestamp',\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'client.identify',\n {\n distinctId: 'new-user-123',\n properties: {\n $set: {\n email: 'user@acme.com',\n plan: 'premium',\n },\n $set_once: {\n first_login: 1700000102,\n },\n },\n },\n ],\n ],\n};\n\n/**\n * Group identify with properties - per-event mapping fires\n * client.groupIdentify() with group properties. silent: true suppresses capture.\n */\nexport const groupIdentifyWithProperties: PostHogStepExample = {\n title: 'Group identify',\n description:\n 'A company update fires PostHog groupIdentify with group type, key, and associated group properties.',\n in: getEvent('company update', {\n timestamp: 1700000103,\n data: {\n company_id: 'company_123',\n company_name: 'Acme',\n plan: 'enterprise',\n },\n }),\n mapping: {\n silent: true,\n settings: {\n group: {\n map: {\n type: { value: 'company' },\n key: 'data.company_id',\n properties: {\n map: {\n name: 'data.company_name',\n plan: 'data.plan',\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'client.groupIdentify',\n {\n groupType: 'company',\n groupKey: 'company_123',\n properties: {\n name: 'Acme',\n plan: 'enterprise',\n },\n },\n ],\n ],\n};\n\n/**\n * Capture with group context - destination-level settings.group resolves\n * type + key (no properties). The capture call includes groups.\n */\nexport const captureWithGroupContext: PostHogStepExample = {\n title: 'Capture with group',\n description:\n 'A destination-level group mapping attaches the resolved group context to every PostHog capture call.',\n in: getEvent('page view', {\n timestamp: 1700000104,\n globals: { pagegroup: 'docs', company_id: 'company_123' },\n }),\n settings: {\n group: {\n map: {\n type: { value: 'company' },\n key: 'globals.company_id',\n },\n },\n },\n out: [\n [\n 'client.capture',\n {\n distinctId: 'us3r',\n event: 'page view',\n properties: {},\n groups: { company: 'company_123' },\n },\n ],\n ],\n};\n\n/**\n * Consent revoked - after analytics consent is granted (PostHog loads and is\n * enabled), revoking it calls client.disable() via the on('consent') handler.\n * The destination is never loaded under denied consent, so the disable is a\n * real revocation of an already-granted destination.\n */\nexport const consentRevoke: PostHogStepExample = {\n title: 'Consent revoked',\n description:\n 'A walker consent command with analytics denied calls client.disable on the PostHog client.',\n command: 'consent',\n before: { analytics: true },\n in: { analytics: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['client.enable'], ['client.disable']],\n};\n\n/**\n * Consent granted - client.enable() is called.\n */\nexport const consentGrant: PostHogStepExample = {\n title: 'Consent granted',\n description:\n 'A walker consent command with analytics granted calls client.enable on the PostHog client.',\n command: 'consent',\n in: { analytics: true } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['client.enable']],\n};\n"],"mappings":"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","names":["z"]}
@@ -6,7 +6,7 @@ interface Settings {
6
6
  /** PostHog project API key (phc_...) */
7
7
  apiKey: string;
8
8
  /** PostHog client instance, populated by init */
9
- client?: PostHog;
9
+ client?: PostHogClient;
10
10
  /** Destination-level identity mapping */
11
11
  identify?: Mapping.Value;
12
12
  /** Destination-level group mapping */
@@ -26,8 +26,21 @@ interface Settings {
26
26
  debug?: boolean;
27
27
  disabled?: boolean;
28
28
  }
29
+ /**
30
+ * The part of a PostHog client this destination calls. `PostHog` from
31
+ * `posthog-node` satisfies it, and so does an injected mock (tests, simulate)
32
+ * without a cast.
33
+ */
34
+ interface PostHogClient {
35
+ capture(props: Parameters<PostHog['capture']>[0]): void;
36
+ identify(props: Parameters<PostHog['identify']>[0]): void;
37
+ groupIdentify(props: Parameters<PostHog['groupIdentify']>[0]): void;
38
+ shutdown(): Promise<void> | void;
39
+ enable(): Promise<void> | void;
40
+ disable(): Promise<void> | void;
41
+ }
29
42
  interface Env extends DestinationServer.Env {
30
- PostHog?: typeof PostHog;
43
+ PostHog?: new (apiKey: string, options?: ConstructorParameters<typeof PostHog>[1]) => PostHogClient;
31
44
  }
32
45
 
33
46
  /**
@@ -6,7 +6,7 @@ interface Settings {
6
6
  /** PostHog project API key (phc_...) */
7
7
  apiKey: string;
8
8
  /** PostHog client instance, populated by init */
9
- client?: PostHog;
9
+ client?: PostHogClient;
10
10
  /** Destination-level identity mapping */
11
11
  identify?: Mapping.Value;
12
12
  /** Destination-level group mapping */
@@ -26,8 +26,21 @@ interface Settings {
26
26
  debug?: boolean;
27
27
  disabled?: boolean;
28
28
  }
29
+ /**
30
+ * The part of a PostHog client this destination calls. `PostHog` from
31
+ * `posthog-node` satisfies it, and so does an injected mock (tests, simulate)
32
+ * without a cast.
33
+ */
34
+ interface PostHogClient {
35
+ capture(props: Parameters<PostHog['capture']>[0]): void;
36
+ identify(props: Parameters<PostHog['identify']>[0]): void;
37
+ groupIdentify(props: Parameters<PostHog['groupIdentify']>[0]): void;
38
+ shutdown(): Promise<void> | void;
39
+ enable(): Promise<void> | void;
40
+ disable(): Promise<void> | void;
41
+ }
29
42
  interface Env extends DestinationServer.Env {
30
- PostHog?: typeof PostHog;
43
+ PostHog?: new (apiKey: string, options?: ConstructorParameters<typeof PostHog>[1]) => PostHogClient;
31
44
  }
32
45
 
33
46
  /**
@@ -71,10 +71,10 @@ var push = {
71
71
  }
72
72
  };
73
73
  var simulation = [
74
- "call:client.capture",
75
- "call:client.identify",
76
- "call:client.groupIdentify",
77
- "call:client.shutdown"
74
+ "call:PostHog.capture",
75
+ "call:PostHog.identify",
76
+ "call:PostHog.groupIdentify",
77
+ "call:PostHog.shutdown"
78
78
  ];
79
79
 
80
80
  // src/examples/step.ts
@@ -50,10 +50,10 @@ var push = {
50
50
  }
51
51
  };
52
52
  var simulation = [
53
- "call:client.capture",
54
- "call:client.identify",
55
- "call:client.groupIdentify",
56
- "call:client.shutdown"
53
+ "call:PostHog.capture",
54
+ "call:PostHog.identify",
55
+ "call:PostHog.groupIdentify",
56
+ "call:PostHog.shutdown"
57
57
  ];
58
58
 
59
59
  // src/examples/step.ts
package/dist/index.d.mts CHANGED
@@ -6,7 +6,7 @@ interface Settings {
6
6
  /** PostHog project API key (phc_...) */
7
7
  apiKey: string;
8
8
  /** PostHog client instance, populated by init */
9
- client?: PostHog;
9
+ client?: PostHogClient;
10
10
  /** Destination-level identity mapping */
11
11
  identify?: Mapping$1.Value;
12
12
  /** Destination-level group mapping */
@@ -31,8 +31,21 @@ interface Mapping {
31
31
  identify?: Mapping$1.Value;
32
32
  group?: Mapping$1.Value;
33
33
  }
34
+ /**
35
+ * The part of a PostHog client this destination calls. `PostHog` from
36
+ * `posthog-node` satisfies it, and so does an injected mock (tests, simulate)
37
+ * without a cast.
38
+ */
39
+ interface PostHogClient {
40
+ capture(props: Parameters<PostHog['capture']>[0]): void;
41
+ identify(props: Parameters<PostHog['identify']>[0]): void;
42
+ groupIdentify(props: Parameters<PostHog['groupIdentify']>[0]): void;
43
+ shutdown(): Promise<void> | void;
44
+ enable(): Promise<void> | void;
45
+ disable(): Promise<void> | void;
46
+ }
34
47
  interface Env extends DestinationServer.Env {
35
- PostHog?: typeof PostHog;
48
+ PostHog?: new (apiKey: string, options?: ConstructorParameters<typeof PostHog>[1]) => PostHogClient;
36
49
  }
37
50
  type Types = Destination$1.Types<Settings, Mapping, Env, InitSettings>;
38
51
  interface Destination extends DestinationServer.Destination<Types> {
@@ -55,6 +68,7 @@ type index_InitFn = InitFn;
55
68
  type index_InitSettings = InitSettings;
56
69
  type index_Mapping = Mapping;
57
70
  type index_PartialConfig = PartialConfig;
71
+ type index_PostHogClient = PostHogClient;
58
72
  type index_PushEvents = PushEvents;
59
73
  type index_PushFn = PushFn;
60
74
  type index_Rule = Rule;
@@ -62,7 +76,7 @@ type index_Rules = Rules;
62
76
  type index_Settings = Settings;
63
77
  type index_Types = Types;
64
78
  declare namespace index {
65
- export type { index_Config as Config, index_Destination as Destination, index_Env as Env, index_InitFn as InitFn, index_InitSettings as InitSettings, index_Mapping as Mapping, index_PartialConfig as PartialConfig, index_PushEvents as PushEvents, index_PushFn as PushFn, index_Rule as Rule, index_Rules as Rules, index_Settings as Settings, index_Types as Types };
79
+ export type { index_Config as Config, index_Destination as Destination, index_Env as Env, index_InitFn as InitFn, index_InitSettings as InitSettings, index_Mapping as Mapping, index_PartialConfig as PartialConfig, index_PostHogClient as PostHogClient, index_PushEvents as PushEvents, index_PushFn as PushFn, index_Rule as Rule, index_Rules as Rules, index_Settings as Settings, index_Types as Types };
66
80
  }
67
81
 
68
82
  declare const destinationPostHog: Destination;
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ interface Settings {
6
6
  /** PostHog project API key (phc_...) */
7
7
  apiKey: string;
8
8
  /** PostHog client instance, populated by init */
9
- client?: PostHog;
9
+ client?: PostHogClient;
10
10
  /** Destination-level identity mapping */
11
11
  identify?: Mapping$1.Value;
12
12
  /** Destination-level group mapping */
@@ -31,8 +31,21 @@ interface Mapping {
31
31
  identify?: Mapping$1.Value;
32
32
  group?: Mapping$1.Value;
33
33
  }
34
+ /**
35
+ * The part of a PostHog client this destination calls. `PostHog` from
36
+ * `posthog-node` satisfies it, and so does an injected mock (tests, simulate)
37
+ * without a cast.
38
+ */
39
+ interface PostHogClient {
40
+ capture(props: Parameters<PostHog['capture']>[0]): void;
41
+ identify(props: Parameters<PostHog['identify']>[0]): void;
42
+ groupIdentify(props: Parameters<PostHog['groupIdentify']>[0]): void;
43
+ shutdown(): Promise<void> | void;
44
+ enable(): Promise<void> | void;
45
+ disable(): Promise<void> | void;
46
+ }
34
47
  interface Env extends DestinationServer.Env {
35
- PostHog?: typeof PostHog;
48
+ PostHog?: new (apiKey: string, options?: ConstructorParameters<typeof PostHog>[1]) => PostHogClient;
36
49
  }
37
50
  type Types = Destination$1.Types<Settings, Mapping, Env, InitSettings>;
38
51
  interface Destination extends DestinationServer.Destination<Types> {
@@ -55,6 +68,7 @@ type index_InitFn = InitFn;
55
68
  type index_InitSettings = InitSettings;
56
69
  type index_Mapping = Mapping;
57
70
  type index_PartialConfig = PartialConfig;
71
+ type index_PostHogClient = PostHogClient;
58
72
  type index_PushEvents = PushEvents;
59
73
  type index_PushFn = PushFn;
60
74
  type index_Rule = Rule;
@@ -62,7 +76,7 @@ type index_Rules = Rules;
62
76
  type index_Settings = Settings;
63
77
  type index_Types = Types;
64
78
  declare namespace index {
65
- export type { index_Config as Config, index_Destination as Destination, index_Env as Env, index_InitFn as InitFn, index_InitSettings as InitSettings, index_Mapping as Mapping, index_PartialConfig as PartialConfig, index_PushEvents as PushEvents, index_PushFn as PushFn, index_Rule as Rule, index_Rules as Rules, index_Settings as Settings, index_Types as Types };
79
+ export type { index_Config as Config, index_Destination as Destination, index_Env as Env, index_InitFn as InitFn, index_InitSettings as InitSettings, index_Mapping as Mapping, index_PartialConfig as PartialConfig, index_PostHogClient as PostHogClient, index_PushEvents as PushEvents, index_PushFn as PushFn, index_Rule as Rule, index_Rules as Rules, index_Settings as Settings, index_Types as Types };
66
80
  }
67
81
 
68
82
  declare const destinationPostHog: Destination;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/push.ts","../src/types/index.ts"],"sourcesContent":["import type { WalkerOS } from '@walkeros/core';\nimport type { Destination, Env, Settings } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationPostHog from './types';\n\nexport const destinationPostHog: Destination = {\n type: 'posthog',\n\n config: {},\n\n async init({ config: partialConfig, env, logger }) {\n const config = getConfig(partialConfig, env as Env | undefined, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n\n async destroy({ config }) {\n const client = (config?.settings as Settings | undefined)?.client;\n if (client) {\n await client.shutdown();\n }\n },\n\n on(type, context) {\n if (type !== 'consent' || !context?.data) return;\n\n const settings = (context.config?.settings || {}) as Settings;\n const client = settings.client;\n if (!client) return;\n\n const consent = context.data as WalkerOS.Consent;\n const required = (context.config as { consent?: WalkerOS.Consent })\n ?.consent;\n if (!required || Object.keys(required).length === 0) return;\n\n const allGranted = Object.keys(required).every(\n (key) => consent[key] === true,\n );\n if (allGranted) {\n client.enable();\n } else {\n client.disable();\n }\n },\n};\n\nexport default destinationPostHog;\n","import type { Config, Env, PartialConfig, Settings } from './types';\nimport type { Logger } from '@walkeros/core';\nimport { PostHog } from 'posthog-node';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n env: Env | undefined,\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { apiKey } = settings;\n\n if (!apiKey) logger.throw('Config settings apiKey missing');\n\n // Extract PostHog SDK options from settings\n const options: Record<string, unknown> = {};\n if (settings.host) options.host = settings.host;\n if (settings.flushAt !== undefined) options.flushAt = settings.flushAt;\n if (settings.flushInterval !== undefined)\n options.flushInterval = settings.flushInterval;\n if (settings.personalApiKey) options.personalApiKey = settings.personalApiKey;\n if (settings.featureFlagsPollingInterval !== undefined)\n options.featureFlagsPollingInterval = settings.featureFlagsPollingInterval;\n if (settings.disableGeoip !== undefined)\n options.disableGeoip = settings.disableGeoip;\n if (settings.disableCompression !== undefined)\n options.disableCompression = settings.disableCompression;\n if (settings.requestTimeout !== undefined)\n options.requestTimeout = settings.requestTimeout;\n if (settings.fetchRetryCount !== undefined)\n options.fetchRetryCount = settings.fetchRetryCount;\n if (settings.fetchRetryDelay !== undefined)\n options.fetchRetryDelay = settings.fetchRetryDelay;\n if (settings.debug !== undefined) options.debug = settings.debug;\n if (settings.disabled !== undefined) options.disabled = settings.disabled;\n\n // Use PostHog from env if available, otherwise use real PostHog\n const PostHogClass = env?.PostHog || PostHog;\n const client = new PostHogClass(apiKey, options);\n\n const settingsConfig: Settings = {\n ...settings,\n apiKey,\n client,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type { PushFn } from './types';\nimport { getMappingValue, isObject, isString } from '@walkeros/core';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, collector },\n) {\n const settings = config.settings!;\n const client = settings.client;\n if (!client) return;\n\n const mappingSettings = (rule?.settings || {}) as Record<string, unknown>;\n\n // Resolve distinctId: rule-level identify wins over destination-level\n const identifyMapping = mappingSettings.identify ?? settings.identify;\n let distinctId: string | undefined;\n let identifyResolved: Record<string, unknown> | undefined;\n\n if (identifyMapping !== undefined) {\n const resolved = await getMappingValue(event, identifyMapping, {\n collector,\n });\n if (isObject(resolved)) {\n identifyResolved = resolved as Record<string, unknown>;\n if (isString(identifyResolved.distinctId)) {\n distinctId = identifyResolved.distinctId as string;\n }\n }\n }\n\n // Fallback distinctId from event.user\n if (!distinctId) {\n distinctId =\n (isString(event.user?.id) ? event.user.id : undefined) ||\n (isString(event.user?.hash) ? event.user.hash : undefined) ||\n (isString(event.user?.session) ? event.user.session : undefined) ||\n 'anonymous';\n }\n\n // 1. Identity - if $set or $set_once present, call client.identify()\n if (identifyResolved) {\n const $set = isObject(identifyResolved.$set)\n ? (identifyResolved.$set as Record<string, unknown>)\n : undefined;\n const $setOnce = isObject(identifyResolved.$set_once)\n ? (identifyResolved.$set_once as Record<string, unknown>)\n : undefined;\n\n if ($set || $setOnce) {\n const properties: Record<string, unknown> = {};\n if ($set) properties.$set = $set;\n if ($setOnce) properties.$set_once = $setOnce;\n client.identify({ distinctId, properties });\n }\n }\n\n // 2. Group - resolve group mapping (rule-level wins)\n const groupMapping = mappingSettings.group ?? settings.group;\n let groups: Record<string, string | number> | undefined;\n\n if (groupMapping !== undefined) {\n const resolved = await getMappingValue(event, groupMapping, {\n collector,\n });\n if (isObject(resolved)) {\n const groupResolved = resolved as Record<string, unknown>;\n const type = groupResolved.type;\n const key = groupResolved.key;\n const properties = isObject(groupResolved.properties)\n ? (groupResolved.properties as Record<string, unknown>)\n : undefined;\n\n if (isString(type) && (isString(key) || typeof key === 'number')) {\n // If properties present, call groupIdentify\n if (properties) {\n client.groupIdentify({\n groupType: type,\n groupKey: String(key),\n properties,\n });\n }\n // Build groups object for capture\n groups = { [type]: key as string | number };\n }\n }\n }\n\n // 3. Capture - unless rule opts out via silent\n if (rule?.silent !== true) {\n const eventName = isString(rule?.name) ? rule.name : event.name;\n const properties = isObject(data) ? (data as Record<string, unknown>) : {};\n\n const captureArgs: Record<string, unknown> = {\n distinctId,\n event: eventName,\n properties,\n };\n if (groups) captureArgs.groups = groups;\n\n client.capture(captureArgs as Parameters<typeof client.capture>[0]);\n }\n};\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer } from '@walkeros/server-core';\nimport type { PostHog } from 'posthog-node';\n\nexport interface Settings {\n /** PostHog project API key (phc_...) */\n apiKey: string;\n /** PostHog client instance, populated by init */\n client?: PostHog;\n /** Destination-level identity mapping */\n identify?: WalkerOSMapping.Value;\n /** Destination-level group mapping */\n group?: WalkerOSMapping.Value;\n /** Event sections to flatten into capture properties */\n include?: string[];\n // PostHog SDK passthrough options\n host?: string;\n flushAt?: number;\n flushInterval?: number;\n personalApiKey?: string;\n featureFlagsPollingInterval?: number;\n disableGeoip?: boolean;\n disableCompression?: boolean;\n requestTimeout?: number;\n fetchRetryCount?: number;\n fetchRetryDelay?: number;\n debug?: boolean;\n disabled?: boolean;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n identify?: WalkerOSMapping.Value;\n group?: WalkerOSMapping.Value;\n}\n\nexport interface Env extends DestinationServer.Env {\n PostHog?: typeof PostHog;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/push.ts","../src/types/index.ts"],"sourcesContent":["import type { WalkerOS } from '@walkeros/core';\nimport type { Destination, Env, Settings } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationPostHog from './types';\n\nexport const destinationPostHog: Destination = {\n type: 'posthog',\n\n config: {},\n\n async init({ config: partialConfig, env, logger }) {\n const config = getConfig(partialConfig, env as Env | undefined, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n\n async destroy({ config }) {\n const client = (config?.settings as Settings | undefined)?.client;\n if (client) {\n await client.shutdown();\n }\n },\n\n on(type, context) {\n if (type !== 'consent' || !context?.data) return;\n\n const settings = (context.config?.settings || {}) as Settings;\n const client = settings.client;\n if (!client) return;\n\n const consent = context.data as WalkerOS.Consent;\n const required = (context.config as { consent?: WalkerOS.Consent })\n ?.consent;\n if (!required || Object.keys(required).length === 0) return;\n\n const allGranted = Object.keys(required).every(\n (key) => consent[key] === true,\n );\n if (allGranted) {\n client.enable();\n } else {\n client.disable();\n }\n },\n};\n\nexport default destinationPostHog;\n","import type { Config, Env, PartialConfig, Settings } from './types';\nimport type { Logger } from '@walkeros/core';\nimport { PostHog } from 'posthog-node';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n env: Env | undefined,\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { apiKey } = settings;\n\n if (!apiKey) logger.throw('Config settings apiKey missing');\n\n // Extract PostHog SDK options from settings\n const options: Record<string, unknown> = {};\n if (settings.host) options.host = settings.host;\n if (settings.flushAt !== undefined) options.flushAt = settings.flushAt;\n if (settings.flushInterval !== undefined)\n options.flushInterval = settings.flushInterval;\n if (settings.personalApiKey) options.personalApiKey = settings.personalApiKey;\n if (settings.featureFlagsPollingInterval !== undefined)\n options.featureFlagsPollingInterval = settings.featureFlagsPollingInterval;\n if (settings.disableGeoip !== undefined)\n options.disableGeoip = settings.disableGeoip;\n if (settings.disableCompression !== undefined)\n options.disableCompression = settings.disableCompression;\n if (settings.requestTimeout !== undefined)\n options.requestTimeout = settings.requestTimeout;\n if (settings.fetchRetryCount !== undefined)\n options.fetchRetryCount = settings.fetchRetryCount;\n if (settings.fetchRetryDelay !== undefined)\n options.fetchRetryDelay = settings.fetchRetryDelay;\n if (settings.debug !== undefined) options.debug = settings.debug;\n if (settings.disabled !== undefined) options.disabled = settings.disabled;\n\n // Use PostHog from env if available, otherwise use real PostHog\n const PostHogClass = env?.PostHog || PostHog;\n const client = new PostHogClass(apiKey, options);\n\n const settingsConfig: Settings = {\n ...settings,\n apiKey,\n client,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type { PushFn } from './types';\nimport { getMappingValue, isObject, isString } from '@walkeros/core';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, collector },\n) {\n const settings = config.settings!;\n const client = settings.client;\n if (!client) return;\n\n const mappingSettings = (rule?.settings || {}) as Record<string, unknown>;\n\n // Resolve distinctId: rule-level identify wins over destination-level\n const identifyMapping = mappingSettings.identify ?? settings.identify;\n let distinctId: string | undefined;\n let identifyResolved: Record<string, unknown> | undefined;\n\n if (identifyMapping !== undefined) {\n const resolved = await getMappingValue(event, identifyMapping, {\n collector,\n });\n if (isObject(resolved)) {\n identifyResolved = resolved as Record<string, unknown>;\n if (isString(identifyResolved.distinctId)) {\n distinctId = identifyResolved.distinctId as string;\n }\n }\n }\n\n // Fallback distinctId from event.user\n if (!distinctId) {\n distinctId =\n (isString(event.user?.id) ? event.user.id : undefined) ||\n (isString(event.user?.hash) ? event.user.hash : undefined) ||\n (isString(event.user?.session) ? event.user.session : undefined) ||\n 'anonymous';\n }\n\n // 1. Identity - if $set or $set_once present, call client.identify()\n if (identifyResolved) {\n const $set = isObject(identifyResolved.$set)\n ? (identifyResolved.$set as Record<string, unknown>)\n : undefined;\n const $setOnce = isObject(identifyResolved.$set_once)\n ? (identifyResolved.$set_once as Record<string, unknown>)\n : undefined;\n\n if ($set || $setOnce) {\n const properties: Record<string, unknown> = {};\n if ($set) properties.$set = $set;\n if ($setOnce) properties.$set_once = $setOnce;\n client.identify({ distinctId, properties });\n }\n }\n\n // 2. Group - resolve group mapping (rule-level wins)\n const groupMapping = mappingSettings.group ?? settings.group;\n let groups: Record<string, string | number> | undefined;\n\n if (groupMapping !== undefined) {\n const resolved = await getMappingValue(event, groupMapping, {\n collector,\n });\n if (isObject(resolved)) {\n const groupResolved = resolved as Record<string, unknown>;\n const type = groupResolved.type;\n const key = groupResolved.key;\n const properties = isObject(groupResolved.properties)\n ? (groupResolved.properties as Record<string, unknown>)\n : undefined;\n\n if (isString(type) && (isString(key) || typeof key === 'number')) {\n // If properties present, call groupIdentify\n if (properties) {\n client.groupIdentify({\n groupType: type,\n groupKey: String(key),\n properties,\n });\n }\n // Build groups object for capture\n groups = { [type]: key as string | number };\n }\n }\n }\n\n // 3. Capture - unless rule opts out via silent\n if (rule?.silent !== true) {\n const eventName = isString(rule?.name) ? rule.name : event.name;\n const properties = isObject(data) ? (data as Record<string, unknown>) : {};\n\n const captureArgs: Record<string, unknown> = {\n distinctId,\n event: eventName,\n properties,\n };\n if (groups) captureArgs.groups = groups;\n\n client.capture(captureArgs as Parameters<typeof client.capture>[0]);\n }\n};\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer } from '@walkeros/server-core';\nimport type { PostHog } from 'posthog-node';\n\nexport interface Settings {\n /** PostHog project API key (phc_...) */\n apiKey: string;\n /** PostHog client instance, populated by init */\n client?: PostHogClient;\n /** Destination-level identity mapping */\n identify?: WalkerOSMapping.Value;\n /** Destination-level group mapping */\n group?: WalkerOSMapping.Value;\n /** Event sections to flatten into capture properties */\n include?: string[];\n // PostHog SDK passthrough options\n host?: string;\n flushAt?: number;\n flushInterval?: number;\n personalApiKey?: string;\n featureFlagsPollingInterval?: number;\n disableGeoip?: boolean;\n disableCompression?: boolean;\n requestTimeout?: number;\n fetchRetryCount?: number;\n fetchRetryDelay?: number;\n debug?: boolean;\n disabled?: boolean;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n identify?: WalkerOSMapping.Value;\n group?: WalkerOSMapping.Value;\n}\n\n/**\n * The part of a PostHog client this destination calls. `PostHog` from\n * `posthog-node` satisfies it, and so does an injected mock (tests, simulate)\n * without a cast.\n */\nexport interface PostHogClient {\n capture(props: Parameters<PostHog['capture']>[0]): void;\n identify(props: Parameters<PostHog['identify']>[0]): void;\n groupIdentify(props: Parameters<PostHog['groupIdentify']>[0]): void;\n shutdown(): Promise<void> | void;\n enable(): Promise<void> | void;\n disable(): Promise<void> | void;\n}\n\nexport interface Env extends DestinationServer.Env {\n PostHog?: new (\n apiKey: string,\n options?: ConstructorParameters<typeof PostHog>[1],\n ) => PostHogClient;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/push.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Config, Env, PartialConfig, Settings } from './types';\nimport type { Logger } from '@walkeros/core';\nimport { PostHog } from 'posthog-node';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n env: Env | undefined,\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { apiKey } = settings;\n\n if (!apiKey) logger.throw('Config settings apiKey missing');\n\n // Extract PostHog SDK options from settings\n const options: Record<string, unknown> = {};\n if (settings.host) options.host = settings.host;\n if (settings.flushAt !== undefined) options.flushAt = settings.flushAt;\n if (settings.flushInterval !== undefined)\n options.flushInterval = settings.flushInterval;\n if (settings.personalApiKey) options.personalApiKey = settings.personalApiKey;\n if (settings.featureFlagsPollingInterval !== undefined)\n options.featureFlagsPollingInterval = settings.featureFlagsPollingInterval;\n if (settings.disableGeoip !== undefined)\n options.disableGeoip = settings.disableGeoip;\n if (settings.disableCompression !== undefined)\n options.disableCompression = settings.disableCompression;\n if (settings.requestTimeout !== undefined)\n options.requestTimeout = settings.requestTimeout;\n if (settings.fetchRetryCount !== undefined)\n options.fetchRetryCount = settings.fetchRetryCount;\n if (settings.fetchRetryDelay !== undefined)\n options.fetchRetryDelay = settings.fetchRetryDelay;\n if (settings.debug !== undefined) options.debug = settings.debug;\n if (settings.disabled !== undefined) options.disabled = settings.disabled;\n\n // Use PostHog from env if available, otherwise use real PostHog\n const PostHogClass = env?.PostHog || PostHog;\n const client = new PostHogClass(apiKey, options);\n\n const settingsConfig: Settings = {\n ...settings,\n apiKey,\n client,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type { PushFn } from './types';\nimport { getMappingValue, isObject, isString } from '@walkeros/core';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, collector },\n) {\n const settings = config.settings!;\n const client = settings.client;\n if (!client) return;\n\n const mappingSettings = (rule?.settings || {}) as Record<string, unknown>;\n\n // Resolve distinctId: rule-level identify wins over destination-level\n const identifyMapping = mappingSettings.identify ?? settings.identify;\n let distinctId: string | undefined;\n let identifyResolved: Record<string, unknown> | undefined;\n\n if (identifyMapping !== undefined) {\n const resolved = await getMappingValue(event, identifyMapping, {\n collector,\n });\n if (isObject(resolved)) {\n identifyResolved = resolved as Record<string, unknown>;\n if (isString(identifyResolved.distinctId)) {\n distinctId = identifyResolved.distinctId as string;\n }\n }\n }\n\n // Fallback distinctId from event.user\n if (!distinctId) {\n distinctId =\n (isString(event.user?.id) ? event.user.id : undefined) ||\n (isString(event.user?.hash) ? event.user.hash : undefined) ||\n (isString(event.user?.session) ? event.user.session : undefined) ||\n 'anonymous';\n }\n\n // 1. Identity - if $set or $set_once present, call client.identify()\n if (identifyResolved) {\n const $set = isObject(identifyResolved.$set)\n ? (identifyResolved.$set as Record<string, unknown>)\n : undefined;\n const $setOnce = isObject(identifyResolved.$set_once)\n ? (identifyResolved.$set_once as Record<string, unknown>)\n : undefined;\n\n if ($set || $setOnce) {\n const properties: Record<string, unknown> = {};\n if ($set) properties.$set = $set;\n if ($setOnce) properties.$set_once = $setOnce;\n client.identify({ distinctId, properties });\n }\n }\n\n // 2. Group - resolve group mapping (rule-level wins)\n const groupMapping = mappingSettings.group ?? settings.group;\n let groups: Record<string, string | number> | undefined;\n\n if (groupMapping !== undefined) {\n const resolved = await getMappingValue(event, groupMapping, {\n collector,\n });\n if (isObject(resolved)) {\n const groupResolved = resolved as Record<string, unknown>;\n const type = groupResolved.type;\n const key = groupResolved.key;\n const properties = isObject(groupResolved.properties)\n ? (groupResolved.properties as Record<string, unknown>)\n : undefined;\n\n if (isString(type) && (isString(key) || typeof key === 'number')) {\n // If properties present, call groupIdentify\n if (properties) {\n client.groupIdentify({\n groupType: type,\n groupKey: String(key),\n properties,\n });\n }\n // Build groups object for capture\n groups = { [type]: key as string | number };\n }\n }\n }\n\n // 3. Capture - unless rule opts out via silent\n if (rule?.silent !== true) {\n const eventName = isString(rule?.name) ? rule.name : event.name;\n const properties = isObject(data) ? (data as Record<string, unknown>) : {};\n\n const captureArgs: Record<string, unknown> = {\n distinctId,\n event: eventName,\n properties,\n };\n if (groups) captureArgs.groups = groups;\n\n client.capture(captureArgs as Parameters<typeof client.capture>[0]);\n }\n};\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer } from '@walkeros/server-core';\nimport type { PostHog } from 'posthog-node';\n\nexport interface Settings {\n /** PostHog project API key (phc_...) */\n apiKey: string;\n /** PostHog client instance, populated by init */\n client?: PostHog;\n /** Destination-level identity mapping */\n identify?: WalkerOSMapping.Value;\n /** Destination-level group mapping */\n group?: WalkerOSMapping.Value;\n /** Event sections to flatten into capture properties */\n include?: string[];\n // PostHog SDK passthrough options\n host?: string;\n flushAt?: number;\n flushInterval?: number;\n personalApiKey?: string;\n featureFlagsPollingInterval?: number;\n disableGeoip?: boolean;\n disableCompression?: boolean;\n requestTimeout?: number;\n fetchRetryCount?: number;\n fetchRetryDelay?: number;\n debug?: boolean;\n disabled?: boolean;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n identify?: WalkerOSMapping.Value;\n group?: WalkerOSMapping.Value;\n}\n\nexport interface Env extends DestinationServer.Env {\n PostHog?: typeof PostHog;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n","import type { WalkerOS } from '@walkeros/core';\nimport type { Destination, Env, Settings } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationPostHog from './types';\n\nexport const destinationPostHog: Destination = {\n type: 'posthog',\n\n config: {},\n\n async init({ config: partialConfig, env, logger }) {\n const config = getConfig(partialConfig, env as Env | undefined, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n\n async destroy({ config }) {\n const client = (config?.settings as Settings | undefined)?.client;\n if (client) {\n await client.shutdown();\n }\n },\n\n on(type, context) {\n if (type !== 'consent' || !context?.data) return;\n\n const settings = (context.config?.settings || {}) as Settings;\n const client = settings.client;\n if (!client) return;\n\n const consent = context.data as WalkerOS.Consent;\n const required = (context.config as { consent?: WalkerOS.Consent })\n ?.consent;\n if (!required || Object.keys(required).length === 0) return;\n\n const allGranted = Object.keys(required).every(\n (key) => consent[key] === true,\n );\n if (allGranted) {\n client.enable();\n } else {\n client.disable();\n }\n },\n};\n\nexport default destinationPostHog;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/config.ts","../src/push.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Config, Env, PartialConfig, Settings } from './types';\nimport type { Logger } from '@walkeros/core';\nimport { PostHog } from 'posthog-node';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n env: Env | undefined,\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { apiKey } = settings;\n\n if (!apiKey) logger.throw('Config settings apiKey missing');\n\n // Extract PostHog SDK options from settings\n const options: Record<string, unknown> = {};\n if (settings.host) options.host = settings.host;\n if (settings.flushAt !== undefined) options.flushAt = settings.flushAt;\n if (settings.flushInterval !== undefined)\n options.flushInterval = settings.flushInterval;\n if (settings.personalApiKey) options.personalApiKey = settings.personalApiKey;\n if (settings.featureFlagsPollingInterval !== undefined)\n options.featureFlagsPollingInterval = settings.featureFlagsPollingInterval;\n if (settings.disableGeoip !== undefined)\n options.disableGeoip = settings.disableGeoip;\n if (settings.disableCompression !== undefined)\n options.disableCompression = settings.disableCompression;\n if (settings.requestTimeout !== undefined)\n options.requestTimeout = settings.requestTimeout;\n if (settings.fetchRetryCount !== undefined)\n options.fetchRetryCount = settings.fetchRetryCount;\n if (settings.fetchRetryDelay !== undefined)\n options.fetchRetryDelay = settings.fetchRetryDelay;\n if (settings.debug !== undefined) options.debug = settings.debug;\n if (settings.disabled !== undefined) options.disabled = settings.disabled;\n\n // Use PostHog from env if available, otherwise use real PostHog\n const PostHogClass = env?.PostHog || PostHog;\n const client = new PostHogClass(apiKey, options);\n\n const settingsConfig: Settings = {\n ...settings,\n apiKey,\n client,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type { PushFn } from './types';\nimport { getMappingValue, isObject, isString } from '@walkeros/core';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, collector },\n) {\n const settings = config.settings!;\n const client = settings.client;\n if (!client) return;\n\n const mappingSettings = (rule?.settings || {}) as Record<string, unknown>;\n\n // Resolve distinctId: rule-level identify wins over destination-level\n const identifyMapping = mappingSettings.identify ?? settings.identify;\n let distinctId: string | undefined;\n let identifyResolved: Record<string, unknown> | undefined;\n\n if (identifyMapping !== undefined) {\n const resolved = await getMappingValue(event, identifyMapping, {\n collector,\n });\n if (isObject(resolved)) {\n identifyResolved = resolved as Record<string, unknown>;\n if (isString(identifyResolved.distinctId)) {\n distinctId = identifyResolved.distinctId as string;\n }\n }\n }\n\n // Fallback distinctId from event.user\n if (!distinctId) {\n distinctId =\n (isString(event.user?.id) ? event.user.id : undefined) ||\n (isString(event.user?.hash) ? event.user.hash : undefined) ||\n (isString(event.user?.session) ? event.user.session : undefined) ||\n 'anonymous';\n }\n\n // 1. Identity - if $set or $set_once present, call client.identify()\n if (identifyResolved) {\n const $set = isObject(identifyResolved.$set)\n ? (identifyResolved.$set as Record<string, unknown>)\n : undefined;\n const $setOnce = isObject(identifyResolved.$set_once)\n ? (identifyResolved.$set_once as Record<string, unknown>)\n : undefined;\n\n if ($set || $setOnce) {\n const properties: Record<string, unknown> = {};\n if ($set) properties.$set = $set;\n if ($setOnce) properties.$set_once = $setOnce;\n client.identify({ distinctId, properties });\n }\n }\n\n // 2. Group - resolve group mapping (rule-level wins)\n const groupMapping = mappingSettings.group ?? settings.group;\n let groups: Record<string, string | number> | undefined;\n\n if (groupMapping !== undefined) {\n const resolved = await getMappingValue(event, groupMapping, {\n collector,\n });\n if (isObject(resolved)) {\n const groupResolved = resolved as Record<string, unknown>;\n const type = groupResolved.type;\n const key = groupResolved.key;\n const properties = isObject(groupResolved.properties)\n ? (groupResolved.properties as Record<string, unknown>)\n : undefined;\n\n if (isString(type) && (isString(key) || typeof key === 'number')) {\n // If properties present, call groupIdentify\n if (properties) {\n client.groupIdentify({\n groupType: type,\n groupKey: String(key),\n properties,\n });\n }\n // Build groups object for capture\n groups = { [type]: key as string | number };\n }\n }\n }\n\n // 3. Capture - unless rule opts out via silent\n if (rule?.silent !== true) {\n const eventName = isString(rule?.name) ? rule.name : event.name;\n const properties = isObject(data) ? (data as Record<string, unknown>) : {};\n\n const captureArgs: Record<string, unknown> = {\n distinctId,\n event: eventName,\n properties,\n };\n if (groups) captureArgs.groups = groups;\n\n client.capture(captureArgs as Parameters<typeof client.capture>[0]);\n }\n};\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer } from '@walkeros/server-core';\nimport type { PostHog } from 'posthog-node';\n\nexport interface Settings {\n /** PostHog project API key (phc_...) */\n apiKey: string;\n /** PostHog client instance, populated by init */\n client?: PostHogClient;\n /** Destination-level identity mapping */\n identify?: WalkerOSMapping.Value;\n /** Destination-level group mapping */\n group?: WalkerOSMapping.Value;\n /** Event sections to flatten into capture properties */\n include?: string[];\n // PostHog SDK passthrough options\n host?: string;\n flushAt?: number;\n flushInterval?: number;\n personalApiKey?: string;\n featureFlagsPollingInterval?: number;\n disableGeoip?: boolean;\n disableCompression?: boolean;\n requestTimeout?: number;\n fetchRetryCount?: number;\n fetchRetryDelay?: number;\n debug?: boolean;\n disabled?: boolean;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n identify?: WalkerOSMapping.Value;\n group?: WalkerOSMapping.Value;\n}\n\n/**\n * The part of a PostHog client this destination calls. `PostHog` from\n * `posthog-node` satisfies it, and so does an injected mock (tests, simulate)\n * without a cast.\n */\nexport interface PostHogClient {\n capture(props: Parameters<PostHog['capture']>[0]): void;\n identify(props: Parameters<PostHog['identify']>[0]): void;\n groupIdentify(props: Parameters<PostHog['groupIdentify']>[0]): void;\n shutdown(): Promise<void> | void;\n enable(): Promise<void> | void;\n disable(): Promise<void> | void;\n}\n\nexport interface Env extends DestinationServer.Env {\n PostHog?: new (\n apiKey: string,\n options?: ConstructorParameters<typeof PostHog>[1],\n ) => PostHogClient;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n","import type { WalkerOS } from '@walkeros/core';\nimport type { Destination, Env, Settings } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationPostHog from './types';\n\nexport const destinationPostHog: Destination = {\n type: 'posthog',\n\n config: {},\n\n async init({ config: partialConfig, env, logger }) {\n const config = getConfig(partialConfig, env as Env | undefined, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n\n async destroy({ config }) {\n const client = (config?.settings as Settings | undefined)?.client;\n if (client) {\n await client.shutdown();\n }\n },\n\n on(type, context) {\n if (type !== 'consent' || !context?.data) return;\n\n const settings = (context.config?.settings || {}) as Settings;\n const client = settings.client;\n if (!client) return;\n\n const consent = context.data as WalkerOS.Consent;\n const required = (context.config as { consent?: WalkerOS.Consent })\n ?.consent;\n if (!required || Object.keys(required).length === 0) return;\n\n const allGranted = Object.keys(required).every(\n (key) => consent[key] === true,\n );\n if (allGranted) {\n client.enable();\n } else {\n client.disable();\n }\n },\n};\n\nexport default destinationPostHog;\n"],"mappings":"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","names":[]}
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "$meta": {
3
3
  "package": "@walkeros/server-destination-posthog",
4
- "version": "4.7.0-next-1790245733116",
4
+ "version": "4.7.0",
5
5
  "type": "destination",
6
6
  "platform": [
7
7
  "server"
8
8
  ],
9
+ "exports": {},
9
10
  "docs": "https://www.walkeros.io/docs/destinations/server/posthog",
10
11
  "source": "https://github.com/elbwalker/walkerOS/tree/main/packages/server/destinations/posthog/src"
11
12
  },
@@ -88,10 +89,10 @@
88
89
  }
89
90
  },
90
91
  "simulation": [
91
- "call:client.capture",
92
- "call:client.identify",
93
- "call:client.groupIdentify",
94
- "call:client.shutdown"
92
+ "call:PostHog.capture",
93
+ "call:PostHog.identify",
94
+ "call:PostHog.groupIdentify",
95
+ "call:PostHog.shutdown"
95
96
  ]
96
97
  },
97
98
  "step": {
@@ -137,7 +138,7 @@
137
138
  "consent": {
138
139
  "functional": true
139
140
  },
140
- "id": "14d35bb668c483d0",
141
+ "id": "fc2a10a73c71297a",
141
142
  "trigger": "load",
142
143
  "entity": "page",
143
144
  "action": "view",
@@ -254,7 +255,7 @@
254
255
  "consent": {
255
256
  "functional": true
256
257
  },
257
- "id": "cfcde4d6473b8c02",
258
+ "id": "696ae764923f8f1c",
258
259
  "trigger": "load",
259
260
  "entity": "order",
260
261
  "action": "complete",
@@ -356,7 +357,7 @@
356
357
  "consent": {
357
358
  "functional": true
358
359
  },
359
- "id": "29cf544585d05dc7",
360
+ "id": "aa5d070cab368219",
360
361
  "trigger": "load",
361
362
  "entity": "product",
362
363
  "action": "view",
@@ -418,7 +419,7 @@
418
419
  "consent": {
419
420
  "functional": true
420
421
  },
421
- "id": "4f37fa35caa5e2dc",
422
+ "id": "976a43d5c28899b1",
422
423
  "trigger": "test",
423
424
  "entity": "company",
424
425
  "action": "update",
@@ -502,7 +503,7 @@
502
503
  "consent": {
503
504
  "functional": true
504
505
  },
505
- "id": "a6a4bff0653e834c",
506
+ "id": "d287da21081b70a3",
506
507
  "trigger": "test",
507
508
  "entity": "user",
508
509
  "action": "login",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@walkeros/server-destination-posthog",
3
3
  "description": "PostHog server destination for walkerOS",
4
- "version": "4.7.0-next-1790245733116",
4
+ "version": "4.7.0",
5
5
  "license": "MIT",
6
6
  "exports": {
7
7
  ".": {
@@ -35,12 +35,12 @@
35
35
  "update": "npx npm-check-updates -u && npm update"
36
36
  },
37
37
  "dependencies": {
38
- "@walkeros/core": "4.7.0-next-1790245733116",
39
- "@walkeros/server-core": "4.7.0-next-1790245733116",
38
+ "@walkeros/core": "4.7.0",
39
+ "@walkeros/server-core": "4.7.0",
40
40
  "posthog-node": "^5.0.0"
41
41
  },
42
42
  "devDependencies": {
43
- "@walkeros/collector": "4.7.0-next-1790245733116"
43
+ "@walkeros/collector": "4.7.0"
44
44
  },
45
45
  "repository": {
46
46
  "url": "git+https://github.com/elbwalker/walkerOS.git",