@segment/analytics-browser-actions-koala 1.0.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/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@segment/analytics-browser-actions-koala",
3
+ "version": "1.0.0",
4
+ "license": "MIT",
5
+ "main": "./dist/cjs",
6
+ "module": "./dist/esm",
7
+ "scripts": {
8
+ "build": "yarn build:esm && yarn build:cjs",
9
+ "build:cjs": "tsc --module commonjs --outDir ./dist/cjs",
10
+ "build:esm": "tsc --outDir ./dist/esm"
11
+ },
12
+ "typings": "./dist/esm",
13
+ "dependencies": {
14
+ "@segment/actions-core": "^3.71.0",
15
+ "@segment/browser-destination-runtime": "^1.0.0"
16
+ },
17
+ "peerDependencies": {
18
+ "@segment/analytics-next": "*"
19
+ }
20
+ }
@@ -0,0 +1,8 @@
1
+ // Generated file. DO NOT MODIFY IT BY HAND.
2
+
3
+ export interface Settings {
4
+ /**
5
+ * Please enter your Public API Key found in your Koala workspace settings.
6
+ */
7
+ project_slug: string
8
+ }
@@ -0,0 +1,70 @@
1
+ import type { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import KoalaDestination, { destination } from '../../index'
4
+
5
+ import { loadScript } from '@segment/browser-destination-runtime/load-script'
6
+ jest.mock('@segment/browser-destination-runtime/load-script')
7
+ beforeEach(async () => {
8
+ ;(loadScript as jest.Mock).mockResolvedValue(true)
9
+ })
10
+
11
+ const subscriptions: Subscription[] = [
12
+ {
13
+ partnerAction: 'identifyVisitor',
14
+ name: 'Identify Visitor',
15
+ enabled: true,
16
+ subscribe: 'type = "identify"',
17
+ mapping: {
18
+ traits: {
19
+ '@path': '$.traits'
20
+ }
21
+ }
22
+ }
23
+ ]
24
+
25
+ describe('Koala.identifyVisitor', () => {
26
+ test('it maps traits and passes them into ko.identify', async () => {
27
+ window.ko = {
28
+ ready: jest.fn(),
29
+ track: jest.fn().mockResolvedValueOnce(undefined),
30
+ identify: jest.fn().mockResolvedValueOnce(undefined)
31
+ }
32
+ window.KoalaSDK = {
33
+ load: jest.fn().mockResolvedValueOnce(window.ko)
34
+ }
35
+
36
+ const [event] = await KoalaDestination({
37
+ subscriptions,
38
+ project_slug: 'koala-test'
39
+ })
40
+
41
+ const ajs = new Analytics({ writeKey: 'w_123' })
42
+ await event.load(Context.system(), ajs)
43
+ jest.spyOn(destination.actions.identifyVisitor, 'perform')
44
+
45
+ await event.identify?.(
46
+ new Context({
47
+ type: 'identify',
48
+ traits: {
49
+ name: 'Matt'
50
+ }
51
+ })
52
+ )
53
+
54
+ expect(destination.actions.identifyVisitor.perform).toHaveBeenCalledWith(
55
+ expect.anything(),
56
+ expect.objectContaining({
57
+ payload: {
58
+ traits: {
59
+ name: 'Matt'
60
+ }
61
+ }
62
+ })
63
+ )
64
+ expect(window.ko.identify).toHaveBeenCalledWith(
65
+ expect.objectContaining({
66
+ name: 'Matt'
67
+ })
68
+ )
69
+ })
70
+ })
@@ -0,0 +1,10 @@
1
+ // Generated file. DO NOT MODIFY IT BY HAND.
2
+
3
+ export interface Payload {
4
+ /**
5
+ * Traits to associate with the visitor in Koala.
6
+ */
7
+ traits: {
8
+ [k: string]: unknown
9
+ }
10
+ }
@@ -0,0 +1,28 @@
1
+ import type { BrowserActionDefinition } from '@segment/browser-destination-runtime/types'
2
+ import type { Settings } from '../generated-types'
3
+ import type { Payload } from './generated-types'
4
+ import type { Koala } from '../types'
5
+
6
+ const action: BrowserActionDefinition<Settings, Koala, Payload> = {
7
+ title: 'Identify Visitor',
8
+ description: 'Update visitor traits in Koala.',
9
+ defaultSubscription: 'type = "identify"',
10
+ platform: 'web',
11
+ fields: {
12
+ traits: {
13
+ type: 'object',
14
+ label: 'Traits',
15
+ description: 'Traits to associate with the visitor in Koala.',
16
+ required: true,
17
+ default: { '@path': '$.traits' },
18
+ defaultObjectUI: 'object'
19
+ }
20
+ },
21
+ perform: (koala, { payload }) => {
22
+ if (payload?.traits) {
23
+ return koala.identify(payload.traits)
24
+ }
25
+ }
26
+ }
27
+
28
+ export default action
package/src/index.ts ADDED
@@ -0,0 +1,66 @@
1
+ import type { Settings } from './generated-types'
2
+ import type { BrowserDestinationDefinition } from '@segment/browser-destination-runtime/types'
3
+ import type { KoalaSDK, Koala } from './types'
4
+ import { defaultValues } from '@segment/actions-core'
5
+ import { browserDestination } from '@segment/browser-destination-runtime/shim'
6
+ import { initScript } from './init-script'
7
+ import trackEvent from './trackEvent'
8
+ import identifyVisitor from './identifyVisitor'
9
+
10
+ declare global {
11
+ interface Window {
12
+ ko: Koala
13
+ KoalaSDK: KoalaSDK
14
+ }
15
+ }
16
+
17
+ export const destination: BrowserDestinationDefinition<Settings, Koala> = {
18
+ name: 'Koala',
19
+ slug: 'actions-koala',
20
+ description: 'Connect Koala in Segment to send visitor events or traits to Koala.',
21
+ mode: 'device',
22
+ settings: {
23
+ project_slug: {
24
+ type: 'string',
25
+ label: 'Public API Key',
26
+ description: 'Please enter your Public API Key found in your Koala workspace settings.',
27
+ required: true
28
+ }
29
+ },
30
+
31
+ initialize: async ({ settings, analytics }, deps) => {
32
+ initScript()
33
+ await deps.loadScript(`https://cdn.koala.live/v1/${settings.project_slug}/umd.js`)
34
+
35
+ const ko = await window.KoalaSDK.load({
36
+ project: settings.project_slug,
37
+ hookSegment: false
38
+ })
39
+
40
+ void analytics.ready(() => ko.ready(() => ko.identify(analytics.user().traits() as Record<string, unknown>)))
41
+
42
+ return ko
43
+ },
44
+
45
+ actions: {
46
+ trackEvent,
47
+ identifyVisitor
48
+ },
49
+
50
+ presets: [
51
+ {
52
+ name: 'Track Event',
53
+ subscribe: 'type = "track"',
54
+ partnerAction: 'trackEvent',
55
+ mapping: defaultValues(trackEvent.fields)
56
+ },
57
+ {
58
+ name: 'Identify Visitor',
59
+ subscribe: 'type = "identify"',
60
+ partnerAction: 'identifyVisitor',
61
+ mapping: defaultValues(identifyVisitor.fields)
62
+ }
63
+ ]
64
+ }
65
+
66
+ export default browserDestination(destination)
@@ -0,0 +1,17 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ export function initScript() {
4
+ if (window.ko) {
5
+ return
6
+ }
7
+
8
+ window.ko = []
9
+ ;['identify', 'track', 'removeListeners', 'open', 'on', 'off', 'qualify', 'ready'].forEach(function (method) {
10
+ ko[method] = function () {
11
+ let args = Array.from(arguments)
12
+ args.unshift(method)
13
+ ko.push(args)
14
+ return ko
15
+ }
16
+ })
17
+ }
@@ -0,0 +1,76 @@
1
+ import type { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import KoalaDestination, { destination } from '../../index'
4
+
5
+ import { loadScript } from '@segment/browser-destination-runtime/load-script'
6
+ jest.mock('@segment/browser-destination-runtime/load-script')
7
+ beforeEach(async () => {
8
+ ;(loadScript as jest.Mock).mockResolvedValue(true)
9
+ })
10
+
11
+ const subscriptions: Subscription[] = [
12
+ {
13
+ partnerAction: 'trackEvent',
14
+ name: 'Track Event',
15
+ enabled: true,
16
+ subscribe: 'type = "track"',
17
+ mapping: {
18
+ event: {
19
+ '@path': '$.event'
20
+ },
21
+ properties: {
22
+ '@path': '$.properties'
23
+ }
24
+ }
25
+ }
26
+ ]
27
+
28
+ describe('Koala.trackEvent', () => {
29
+ test('it maps the event name and properties and passes them into ko.track', async () => {
30
+ window.ko = {
31
+ ready: jest.fn(),
32
+ track: jest.fn().mockResolvedValueOnce(undefined),
33
+ identify: jest.fn().mockResolvedValueOnce(undefined)
34
+ }
35
+ window.KoalaSDK = {
36
+ load: jest.fn().mockResolvedValueOnce(window.ko)
37
+ }
38
+
39
+ const [event] = await KoalaDestination({
40
+ subscriptions,
41
+ project_slug: 'koala-test'
42
+ })
43
+
44
+ const ajs = new Analytics({ writeKey: 'w_123' })
45
+ await event.load(Context.system(), ajs)
46
+ jest.spyOn(destination.actions.trackEvent, 'perform')
47
+
48
+ await event.track?.(
49
+ new Context({
50
+ type: 'track',
51
+ event: 'Form Submitted',
52
+ properties: {
53
+ is_new_subscriber: true
54
+ }
55
+ })
56
+ )
57
+
58
+ expect(destination.actions.trackEvent.perform).toHaveBeenCalledWith(
59
+ expect.anything(),
60
+ expect.objectContaining({
61
+ payload: {
62
+ event: 'Form Submitted',
63
+ properties: {
64
+ is_new_subscriber: true
65
+ }
66
+ }
67
+ })
68
+ )
69
+ expect(window.ko.track).toHaveBeenCalledWith(
70
+ 'Form Submitted',
71
+ expect.objectContaining({
72
+ is_new_subscriber: true
73
+ })
74
+ )
75
+ })
76
+ })
@@ -0,0 +1,14 @@
1
+ // Generated file. DO NOT MODIFY IT BY HAND.
2
+
3
+ export interface Payload {
4
+ /**
5
+ * The event name.
6
+ */
7
+ event: string
8
+ /**
9
+ * Properties to send with the event.
10
+ */
11
+ properties?: {
12
+ [k: string]: unknown
13
+ }
14
+ }
@@ -0,0 +1,35 @@
1
+ import type { BrowserActionDefinition } from '@segment/browser-destination-runtime/types'
2
+ import type { Settings } from '../generated-types'
3
+ import type { Payload } from './generated-types'
4
+ import type { Koala } from '../types'
5
+
6
+ const action: BrowserActionDefinition<Settings, Koala, Payload> = {
7
+ title: 'Track Event',
8
+ description: 'Send visitor events to Koala.',
9
+ defaultSubscription: 'type = "track"',
10
+ platform: 'web',
11
+ fields: {
12
+ event: {
13
+ type: 'string',
14
+ required: true,
15
+ description: 'The event name.',
16
+ label: 'Event Name',
17
+ default: { '@path': '$.event' }
18
+ },
19
+ properties: {
20
+ type: 'object',
21
+ required: false,
22
+ description: 'Properties to send with the event.',
23
+ label: 'Event Properties',
24
+ default: { '@path': '$.properties' },
25
+ defaultObjectUI: 'object'
26
+ }
27
+ },
28
+ perform: (koala, { payload }) => {
29
+ if (payload?.event) {
30
+ return koala.track(payload.event, payload.properties)
31
+ }
32
+ }
33
+ }
34
+
35
+ export default action
package/src/types.ts ADDED
@@ -0,0 +1,9 @@
1
+ export interface Koala {
2
+ ready: (fn?: () => Promise<unknown> | unknown) => Promise<void>
3
+ track: (event: string, data?: { [key: string]: unknown }) => Promise<void>
4
+ identify: (traits: Record<string, unknown>) => Promise<void>
5
+ }
6
+
7
+ export interface KoalaSDK {
8
+ load: (options: { project: string; hookSegment?: boolean }) => Promise<Koala>
9
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.build.json",
3
+ "compilerOptions": {
4
+ "rootDir": "./src",
5
+ "baseUrl": "."
6
+ },
7
+ "include": ["src"],
8
+ "exclude": ["dist", "**/__tests__"]
9
+ }