@segment/analytics-browser-actions-iterate 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-iterate",
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,62 @@
1
+ import { Analytics, Context } from '@segment/analytics-next'
2
+ import iterateDestination, { destination } from '../index'
3
+ import { Subscription } from '@segment/browser-destination-runtime/types'
4
+
5
+ const subscriptions: Subscription[] = [
6
+ {
7
+ partnerAction: 'trackEvent',
8
+ name: 'Track Event',
9
+ enabled: true,
10
+ subscribe: 'type = "track"',
11
+ mapping: {
12
+ name: {
13
+ '@path': '$.name'
14
+ }
15
+ }
16
+ }
17
+ ]
18
+
19
+ describe('Iterate initialization', () => {
20
+ test('can load Iterate', async () => {
21
+ const [event] = await iterateDestination({
22
+ apiKey: 'abc123',
23
+ subscriptions
24
+ })
25
+
26
+ jest.spyOn(destination.actions.trackEvent, 'perform')
27
+ jest.spyOn(destination, 'initialize')
28
+
29
+ await event.load(Context.system(), {} as Analytics)
30
+ expect(destination.initialize).toHaveBeenCalled()
31
+
32
+ const ctx = await event.track?.(
33
+ new Context({
34
+ type: 'track',
35
+ name: 'example-event'
36
+ })
37
+ )
38
+
39
+ expect(destination.actions.trackEvent.perform).toHaveBeenCalled()
40
+ expect(ctx).not.toBeUndefined()
41
+
42
+ const scripts = window.document.querySelectorAll('script')
43
+ scripts[0].src = scripts[0].src.replace(/match-prod-.*.js/, 'match-prod.js')
44
+ expect(scripts).toMatchInlineSnapshot(`
45
+ NodeList [
46
+ <script
47
+ id="iterate-script"
48
+ src="https://platform.iteratehq.com/match-prod.js"
49
+ type="text/javascript"
50
+ />,
51
+ <script
52
+ src="https://platform.iteratehq.com/loader.js"
53
+ status="loaded"
54
+ type="text/javascript"
55
+ />,
56
+ <script>
57
+ // the emptiness
58
+ </script>,
59
+ ]
60
+ `)
61
+ })
62
+ })
@@ -0,0 +1,8 @@
1
+ // Generated file. DO NOT MODIFY IT BY HAND.
2
+
3
+ export interface Settings {
4
+ /**
5
+ * The Embed API Key for your account. You can find this on your settings pages.
6
+ */
7
+ apiKey: string
8
+ }
@@ -0,0 +1,52 @@
1
+ import { Analytics, Context } from '@segment/analytics-next'
2
+ import iterateDestination, { destination } from '../../index'
3
+
4
+ describe('Iterate.identifyUser', () => {
5
+ it('Should call identify', async () => {
6
+ const [identifyEvent] = await iterateDestination({
7
+ apiKey: '123',
8
+ subscriptions: [
9
+ {
10
+ partnerAction: 'identifyUser',
11
+ name: 'Identify User',
12
+ enabled: true,
13
+ subscribe: 'type = "identify"',
14
+ mapping: {
15
+ userId: {
16
+ '@path': '$.userId'
17
+ },
18
+ traits: {
19
+ '@path': '$.traits'
20
+ }
21
+ }
22
+ }
23
+ ]
24
+ })
25
+
26
+ destination.actions.identifyUser.perform = jest.fn()
27
+ const identifySpy = jest.spyOn(destination.actions.identifyUser, 'perform')
28
+ await identifyEvent.load(Context.system(), {} as Analytics)
29
+
30
+ await identifyEvent.identify?.(
31
+ new Context({
32
+ type: 'identify',
33
+ userId: '123abc',
34
+ traits: {
35
+ foo: 'bar'
36
+ }
37
+ })
38
+ )
39
+
40
+ expect(identifySpy).toHaveBeenCalledWith(
41
+ expect.anything(),
42
+ expect.objectContaining({
43
+ payload: {
44
+ userId: '123abc',
45
+ traits: {
46
+ foo: 'bar'
47
+ }
48
+ }
49
+ })
50
+ )
51
+ })
52
+ })
@@ -0,0 +1,14 @@
1
+ // Generated file. DO NOT MODIFY IT BY HAND.
2
+
3
+ export interface Payload {
4
+ /**
5
+ * The user's identity.
6
+ */
7
+ userId?: string
8
+ /**
9
+ * The Segment traits to be forwarded to Iterate.
10
+ */
11
+ traits?: {
12
+ [k: string]: unknown
13
+ }
14
+ }
@@ -0,0 +1,42 @@
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 { Iterate as IterateClient, Command } from '../types'
5
+
6
+ const action: BrowserActionDefinition<Settings, IterateClient, Payload> = {
7
+ title: 'Identify User',
8
+ description: 'Sets user identity',
9
+ platform: 'web',
10
+ defaultSubscription: 'type = "identify"',
11
+ fields: {
12
+ userId: {
13
+ type: 'string',
14
+ required: false,
15
+ description: "The user's identity.",
16
+ label: 'Identity',
17
+ default: {
18
+ '@path': '$.userId'
19
+ }
20
+ },
21
+ traits: {
22
+ type: 'object',
23
+ required: false,
24
+ description: 'The Segment traits to be forwarded to Iterate.',
25
+ label: 'Traits',
26
+ default: {
27
+ '@path': '$.traits'
28
+ }
29
+ }
30
+ },
31
+ perform: (Iterate, event) => {
32
+ const traits = event.payload.traits || {}
33
+
34
+ if (event.payload.userId) {
35
+ traits['external_id'] = event.payload.userId
36
+ }
37
+
38
+ Iterate(Command.Identify, traits)
39
+ }
40
+ }
41
+
42
+ export default action
package/src/index.ts ADDED
@@ -0,0 +1,80 @@
1
+ import type { BrowserDestinationDefinition } from '@segment/browser-destination-runtime/types'
2
+ import { browserDestination } from '@segment/browser-destination-runtime/shim'
3
+ import type { Settings } from './generated-types'
4
+ import { Iterate, IterateApi, IterateSettings } from './types'
5
+ import { defaultValues } from '@segment/actions-core'
6
+
7
+ import trackEvent from './trackEvent'
8
+ import identifyUser from './identifyUser'
9
+
10
+ // Declare global to access your client
11
+ declare global {
12
+ interface Window {
13
+ Iterate: Iterate
14
+ iterateSettings: IterateSettings
15
+ IterateObjectName: string
16
+ }
17
+ }
18
+
19
+ // Switch from unknown to the partner SDK client types
20
+ export const destination: BrowserDestinationDefinition<Settings, Iterate> = {
21
+ name: 'Iterate Web (Actions)',
22
+ slug: 'actions-iterate',
23
+ mode: 'device',
24
+ presets: [
25
+ {
26
+ name: 'Track Event',
27
+ subscribe: 'type = "track"',
28
+ partnerAction: 'trackEvent',
29
+ mapping: defaultValues(trackEvent.fields)
30
+ },
31
+ {
32
+ name: 'Identify User',
33
+ subscribe: 'type = "identify"',
34
+ partnerAction: 'identifyUser',
35
+ mapping: defaultValues(identifyUser.fields)
36
+ }
37
+ ],
38
+
39
+ settings: {
40
+ // Add any Segment destination settings required here
41
+ apiKey: {
42
+ label: 'Embed API Key',
43
+ description: 'The Embed API Key for your account. You can find this on your settings pages.',
44
+ type: 'string',
45
+ required: true
46
+ }
47
+ },
48
+
49
+ initialize: async ({ settings }, deps) => {
50
+ // initialize settings
51
+ window.iterateSettings = {
52
+ apiKey: settings.apiKey,
53
+ installOnLoad: false
54
+ }
55
+ window.IterateObjectName = 'Iterate'
56
+
57
+ // Initialize placeholder Iterate command
58
+ const iteratePlaceholder = <IterateApi>function (...args) {
59
+ iteratePlaceholder.command(args)
60
+ }
61
+ iteratePlaceholder.loaded = false
62
+ iteratePlaceholder.q = []
63
+ iteratePlaceholder.command = function (args: unknown[]) {
64
+ iteratePlaceholder.q.push(args)
65
+ }
66
+ window.Iterate = iteratePlaceholder
67
+
68
+ await deps.loadScript('https://platform.iteratehq.com/loader.js')
69
+ await deps.resolveWhen(() => !Object.prototype.hasOwnProperty.call(window.Iterate, 'loaded'), 100)
70
+
71
+ return window.Iterate
72
+ },
73
+
74
+ actions: {
75
+ trackEvent,
76
+ identifyUser
77
+ }
78
+ }
79
+
80
+ export default browserDestination(destination)
@@ -0,0 +1,43 @@
1
+ import { Analytics, Context } from '@segment/analytics-next'
2
+ import iterateDestination, { destination } from '../../index'
3
+
4
+ describe('Iterate.trackEvent', () => {
5
+ it('Sends events to Iterate', async () => {
6
+ const [trackEvent] = await iterateDestination({
7
+ apiKey: 'abc123',
8
+ subscriptions: [
9
+ {
10
+ partnerAction: 'trackEvent',
11
+ name: 'Track Event',
12
+ enabled: true,
13
+ subscribe: 'type = "track"',
14
+ mapping: {
15
+ name: {
16
+ '@path': '$.name'
17
+ }
18
+ }
19
+ }
20
+ ]
21
+ })
22
+
23
+ destination.actions.trackEvent.perform = jest.fn()
24
+ const trackSpy = jest.spyOn(destination.actions.trackEvent, 'perform')
25
+ await trackEvent.load(Context.system(), {} as Analytics)
26
+
27
+ await trackEvent.track?.(
28
+ new Context({
29
+ type: 'track',
30
+ name: 'example-event'
31
+ })
32
+ )
33
+
34
+ expect(trackSpy).toHaveBeenCalledWith(
35
+ expect.anything(),
36
+ expect.objectContaining({
37
+ payload: {
38
+ name: 'example-event'
39
+ }
40
+ })
41
+ )
42
+ })
43
+ })
@@ -0,0 +1,8 @@
1
+ // Generated file. DO NOT MODIFY IT BY HAND.
2
+
3
+ export interface Payload {
4
+ /**
5
+ * The name of the event.
6
+ */
7
+ name: string
8
+ }
@@ -0,0 +1,27 @@
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 { Iterate as IterateClient, Command } from '../types'
5
+
6
+ const action: BrowserActionDefinition<Settings, IterateClient, Payload> = {
7
+ title: 'Track Event',
8
+ description: 'Track events',
9
+ platform: 'web',
10
+ defaultSubscription: 'type = "track"',
11
+ fields: {
12
+ name: {
13
+ description: 'The name of the event.',
14
+ label: 'Name',
15
+ required: true,
16
+ type: 'string',
17
+ default: {
18
+ '@path': '$.event'
19
+ }
20
+ }
21
+ },
22
+ perform: (Iterate, event) => {
23
+ Iterate(Command.Event, event.payload.name)
24
+ }
25
+ }
26
+
27
+ export default action
package/src/types.ts ADDED
@@ -0,0 +1,23 @@
1
+ export type Iterate = (command: Command, ...args: unknown[]) => void
2
+
3
+ export enum Command {
4
+ Event = 'event',
5
+ Install = 'install',
6
+ Identify = 'identify',
7
+ OnResponse = 'onResponse',
8
+ OnLoad = 'onLoad',
9
+ onClose = 'onClose',
10
+ Uninstall = 'uninstall'
11
+ }
12
+
13
+ export type IterateApi = {
14
+ (): void
15
+ q: unknown[]
16
+ command: (args: unknown[]) => void
17
+ loaded: boolean
18
+ }
19
+
20
+ export type IterateSettings = {
21
+ apiKey: string
22
+ installOnLoad?: boolean
23
+ }
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
+ }