@walkeros/web-destination-linkedin 3.3.0-next-1776098542393
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/LICENSE +21 -0
- package/README.md +202 -0
- package/dist/dev.d.mts +229 -0
- package/dist/dev.d.ts +229 -0
- package/dist/dev.js +1 -0
- package/dist/dev.js.map +1 -0
- package/dist/dev.mjs +1 -0
- package/dist/dev.mjs.map +1 -0
- package/dist/examples/index.d.mts +191 -0
- package/dist/examples/index.d.ts +191 -0
- package/dist/examples/index.js +14372 -0
- package/dist/examples/index.mjs +14350 -0
- package/dist/index.browser.js +1 -0
- package/dist/index.d.mts +105 -0
- package/dist/index.d.ts +105 -0
- package/dist/index.es5.js +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -0
- package/dist/walkerOS.json +796 -0
- package/package.json +78 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 elbWalker GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# LinkedIn Web Destination for walkerOS
|
|
2
|
+
|
|
3
|
+
Forward walkerOS events as LinkedIn Insight Tag conversions
|
|
4
|
+
(`window.lintrk('track', ...)`) — opt-in, per-event, with value + currency +
|
|
5
|
+
deduplication support.
|
|
6
|
+
|
|
7
|
+
## Source Code
|
|
8
|
+
|
|
9
|
+
[github.com/elbwalker/walkerOS/tree/main/packages/web/destinations/linkedin](https://github.com/elbwalker/walkerOS/tree/main/packages/web/destinations/linkedin)
|
|
10
|
+
|
|
11
|
+
## NPM
|
|
12
|
+
|
|
13
|
+
[`@walkeros/web-destination-linkedin`](https://www.npmjs.com/package/@walkeros/web-destination-linkedin)
|
|
14
|
+
|
|
15
|
+
## Documentation
|
|
16
|
+
|
|
17
|
+
[walkeros.io/docs/destinations/web/linkedin](https://www.walkeros.io/docs/destinations/web/linkedin)
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- **Opt-in conversion forwarding** — only events with
|
|
22
|
+
`mapping.settings.conversion` fire a `lintrk('track')` call. Unmapped events
|
|
23
|
+
are silently ignored (Campaign Manager requires pre-registered conversion
|
|
24
|
+
rules).
|
|
25
|
+
- **Automatic page view + retargeting** — the Insight Tag script fires its own
|
|
26
|
+
page view on load for audience building. The destination does not suppress or
|
|
27
|
+
duplicate it.
|
|
28
|
+
- **Conversion value + currency** — `data.total`-style mappings with a currency
|
|
29
|
+
fallback via `{ key, value }` syntax (defaults to `"EUR"`).
|
|
30
|
+
- **Deduplication ready** — maps the walkerOS event `id` to LinkedIn's
|
|
31
|
+
`event_id`, ready for cross-channel deduplication with a future server
|
|
32
|
+
(Conversions API) destination.
|
|
33
|
+
- **Consent-gated** — LinkedIn requires `marketing` consent. The collector's
|
|
34
|
+
`config.consent` gate blocks events until granted; deferred script injection
|
|
35
|
+
is supported via `loadScript: true`.
|
|
36
|
+
- **Script-tag loader** — no npm SDK dependency. The destination injects
|
|
37
|
+
`https://snap.licdn.com/li.lms-analytics/insight.min.js` at runtime (opt-in
|
|
38
|
+
via `loadScript: true`), or you can embed the Insight Tag snippet in your HTML
|
|
39
|
+
and leave `loadScript: false`.
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install @walkeros/web-destination-linkedin
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Quick Start
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"destinations": {
|
|
52
|
+
"linkedin": {
|
|
53
|
+
"package": "@walkeros/web-destination-linkedin",
|
|
54
|
+
"config": {
|
|
55
|
+
"consent": { "marketing": true },
|
|
56
|
+
"loadScript": true,
|
|
57
|
+
"settings": {
|
|
58
|
+
"apiKey": "123456"
|
|
59
|
+
},
|
|
60
|
+
"mapping": {
|
|
61
|
+
"order": {
|
|
62
|
+
"complete": {
|
|
63
|
+
"settings": {
|
|
64
|
+
"conversion": {
|
|
65
|
+
"map": {
|
|
66
|
+
"id": { "value": 67890 },
|
|
67
|
+
"value": "data.total",
|
|
68
|
+
"currency": { "key": "data.currency", "value": "EUR" },
|
|
69
|
+
"eventId": "id"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Configuration
|
|
83
|
+
|
|
84
|
+
### Settings
|
|
85
|
+
|
|
86
|
+
| Key | Type | Required | Notes |
|
|
87
|
+
| --------- | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
88
|
+
| `apiKey` | `string` | yes | LinkedIn Partner ID (numeric string, e.g. `"123456"`). Find it in Campaign Manager → Insight Tag → Manage Insight Tag. |
|
|
89
|
+
| `include` | `string[]` | no | Event sections made available for mapping resolution. Present for consistency with other destinations — `lintrk()` only accepts four fixed fields, so included data is not automatically sent. |
|
|
90
|
+
|
|
91
|
+
### Mapping (per-event)
|
|
92
|
+
|
|
93
|
+
| Key | Resolved shape | Notes |
|
|
94
|
+
| --------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
95
|
+
| `settings.conversion` | `{ id, value?, currency?, eventId? }` | Required for the event to fire. `id` → `conversion_id` (number). Others translate 1:1 to LinkedIn's `conversion_value` / `currency` / `event_id`. |
|
|
96
|
+
|
|
97
|
+
**Falsy guards:**
|
|
98
|
+
|
|
99
|
+
- If `id` resolves to falsy/zero → the entire `lintrk` call is skipped (no
|
|
100
|
+
silent error).
|
|
101
|
+
- If `value` / `currency` / `eventId` resolve to falsy → those fields are
|
|
102
|
+
omitted from the call (`id` still required).
|
|
103
|
+
|
|
104
|
+
## Events
|
|
105
|
+
|
|
106
|
+
### Opt-in model
|
|
107
|
+
|
|
108
|
+
LinkedIn is an **opt-in conversion platform**. Every tracked event must
|
|
109
|
+
reference a pre-created Conversion Rule in Campaign Manager via its numeric
|
|
110
|
+
`conversion_id`. Events without an explicit `mapping.settings.conversion` are
|
|
111
|
+
silently ignored — they produce zero `lintrk` calls.
|
|
112
|
+
|
|
113
|
+
This is the opposite of analytics destinations (Amplitude, Clarity, PostHog)
|
|
114
|
+
which forward every event by default.
|
|
115
|
+
|
|
116
|
+
### Conversion with value and deduplication
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
"mapping": {
|
|
120
|
+
"order": {
|
|
121
|
+
"complete": {
|
|
122
|
+
"settings": {
|
|
123
|
+
"conversion": {
|
|
124
|
+
"map": {
|
|
125
|
+
"id": { "value": 67890 },
|
|
126
|
+
"value": "data.total",
|
|
127
|
+
"currency": { "key": "data.currency", "value": "EUR" },
|
|
128
|
+
"eventId": "id"
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Resolves to:
|
|
138
|
+
`lintrk('track', { conversion_id: 67890, conversion_value: 555, currency: 'EUR', event_id: '<walker-event-id>' })`.
|
|
139
|
+
|
|
140
|
+
### Skipping a fully configured rule
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
"mapping": {
|
|
144
|
+
"form": {
|
|
145
|
+
"submit": {
|
|
146
|
+
"skip": true,
|
|
147
|
+
"settings": {
|
|
148
|
+
"conversion": { "map": { "id": { "value": 12345 } } }
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`mapping.skip: true` suppresses the call while keeping the rule on disk for
|
|
156
|
+
quick reactivation. Alternatively, simply omit `settings.conversion` —
|
|
157
|
+
LinkedIn's opt-in model makes that equivalent.
|
|
158
|
+
|
|
159
|
+
## Consent
|
|
160
|
+
|
|
161
|
+
LinkedIn is an advertising platform. The Insight Tag falls under **marketing**
|
|
162
|
+
consent (not analytics):
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
"config": {
|
|
166
|
+
"consent": { "marketing": true }
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
walkerOS's collector blocks all events to this destination until `marketing` is
|
|
171
|
+
granted. When consent is later revoked, walkerOS stops sending events — the
|
|
172
|
+
LinkedIn Insight Tag itself has no `opt_out()` API, so the tag remains loaded
|
|
173
|
+
but receives no further calls.
|
|
174
|
+
|
|
175
|
+
### Deferred script load
|
|
176
|
+
|
|
177
|
+
If you want the Insight Tag script to load **only** after consent is granted,
|
|
178
|
+
set `loadScript: true` and leave `config.consent.marketing` un-granted at init
|
|
179
|
+
time. The destination will skip `addScript()` during init and inject the script
|
|
180
|
+
when an `on('consent')` event grants marketing.
|
|
181
|
+
|
|
182
|
+
## No identity tracking
|
|
183
|
+
|
|
184
|
+
LinkedIn identity on the web is cookie-based — the Insight Tag manages its own
|
|
185
|
+
first-party cookies and matches visitors against LinkedIn member profiles
|
|
186
|
+
server-side. There is no `lintrk('identify', ...)` API. The destination does
|
|
187
|
+
**not** forward user IDs, emails, phone numbers, or the `li_fat_id` click ID.
|
|
188
|
+
|
|
189
|
+
Click-ID capture (including `li_fat_id`) is the session source's responsibility.
|
|
190
|
+
A future `@walkeros/server-destination-linkedin` (Conversions API) will consume
|
|
191
|
+
`li_fat_id` from `user.device` for advanced matching.
|
|
192
|
+
|
|
193
|
+
## Future: Conversions API
|
|
194
|
+
|
|
195
|
+
A server-side Conversions API destination is planned as a follow-up, matching
|
|
196
|
+
the TikTok / Pinterest / Meta pattern. It will share the `event_id` field with
|
|
197
|
+
this web destination for cross-channel deduplication.
|
|
198
|
+
|
|
199
|
+
## Related
|
|
200
|
+
|
|
201
|
+
- Insight Tag official docs:
|
|
202
|
+
[LinkedIn Help Center](https://www.linkedin.com/help/lms/answer/a427660)
|
package/dist/dev.d.mts
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import * as _walkeros_core_dev from '@walkeros/core/dev';
|
|
2
|
+
import { z } from '@walkeros/core/dev';
|
|
3
|
+
import { DestinationWeb } from '@walkeros/web-core';
|
|
4
|
+
import { Flow } from '@walkeros/core';
|
|
5
|
+
|
|
6
|
+
declare const SettingsSchema: z.ZodObject<{
|
|
7
|
+
apiKey: z.ZodString;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
type Settings$1 = z.infer<typeof SettingsSchema>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* LinkedIn per-rule mapping schema.
|
|
13
|
+
*
|
|
14
|
+
* Every field on `conversion` is a walkerOS mapping value (static literal,
|
|
15
|
+
* string path, or `{ map, value, key, fn, ... }` object). The schema uses
|
|
16
|
+
* `z.unknown()` for each so users can supply any valid mapping shape — the
|
|
17
|
+
* destination resolves it via `getMappingValue()` at push time.
|
|
18
|
+
*/
|
|
19
|
+
declare const MappingSchema: z.ZodObject<{
|
|
20
|
+
conversion: z.ZodOptional<z.ZodUnknown>;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
type Mapping = z.infer<typeof MappingSchema>;
|
|
23
|
+
|
|
24
|
+
declare const settings: _walkeros_core_dev.JSONSchema;
|
|
25
|
+
declare const mapping: _walkeros_core_dev.JSONSchema;
|
|
26
|
+
|
|
27
|
+
type index$1_Mapping = Mapping;
|
|
28
|
+
declare const index$1_MappingSchema: typeof MappingSchema;
|
|
29
|
+
declare const index$1_SettingsSchema: typeof SettingsSchema;
|
|
30
|
+
declare const index$1_mapping: typeof mapping;
|
|
31
|
+
declare const index$1_settings: typeof settings;
|
|
32
|
+
declare namespace index$1 {
|
|
33
|
+
export { type index$1_Mapping as Mapping, index$1_MappingSchema as MappingSchema, type Settings$1 as Settings, index$1_SettingsSchema as SettingsSchema, index$1_mapping as mapping, index$1_settings as settings };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* LinkedIn Insight Tag runtime surface.
|
|
38
|
+
*
|
|
39
|
+
* The Insight Tag script installs `window.lintrk` — a single function that
|
|
40
|
+
* accepts exactly one tracked action: `lintrk('track', data)`.
|
|
41
|
+
*
|
|
42
|
+
* Before the script loads, the destination installs a queue-backed shim so
|
|
43
|
+
* calls made during init are buffered and flushed once the script loads.
|
|
44
|
+
* This mirrors the pattern LinkedIn's own snippet uses.
|
|
45
|
+
*/
|
|
46
|
+
type LintrkAction = 'track';
|
|
47
|
+
interface LintrkTrackData {
|
|
48
|
+
conversion_id: number;
|
|
49
|
+
conversion_value?: number;
|
|
50
|
+
currency?: string;
|
|
51
|
+
event_id?: string;
|
|
52
|
+
}
|
|
53
|
+
type Lintrk = ((action: LintrkAction, data: LintrkTrackData) => void) & {
|
|
54
|
+
/** Internal queue populated before the CDN script loads. */
|
|
55
|
+
q?: unknown[];
|
|
56
|
+
};
|
|
57
|
+
declare global {
|
|
58
|
+
interface Window {
|
|
59
|
+
_linkedin_partner_id?: string;
|
|
60
|
+
_linkedin_data_partner_ids?: string[];
|
|
61
|
+
lintrk?: Lintrk;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Destination-level settings.
|
|
66
|
+
*
|
|
67
|
+
* apiKey — the LinkedIn Partner ID (numeric string, e.g. "123456"), assigned
|
|
68
|
+
* to `window._linkedin_partner_id` before the script loads.
|
|
69
|
+
* include — event sections made available for mapping resolution. Present for
|
|
70
|
+
* consistency with other destinations; has no effect at call time
|
|
71
|
+
* because `lintrk()` only accepts four fixed fields. Kept so users
|
|
72
|
+
* can reference section-prefixed keys in future custom mapping
|
|
73
|
+
* strategies without a breaking change.
|
|
74
|
+
*/
|
|
75
|
+
interface Settings {
|
|
76
|
+
apiKey: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Env — mock surface for tests and dev. The destination mutates
|
|
80
|
+
* `window._linkedin_partner_id` / `window._linkedin_data_partner_ids` and
|
|
81
|
+
* installs `window.lintrk` in init; tests can pre-seed `window.lintrk` with
|
|
82
|
+
* a spy to skip the script injection path.
|
|
83
|
+
*
|
|
84
|
+
* `document` is also mocked so `addScript()` can run headlessly.
|
|
85
|
+
*/
|
|
86
|
+
interface Env extends DestinationWeb.Env {
|
|
87
|
+
window: {
|
|
88
|
+
_linkedin_partner_id?: string;
|
|
89
|
+
_linkedin_data_partner_ids?: string[];
|
|
90
|
+
lintrk?: Lintrk;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Pre-init environment — no LinkedIn state present. The destination's init
|
|
96
|
+
* will populate _linkedin_partner_id and install the lintrk queue.
|
|
97
|
+
*/
|
|
98
|
+
declare const init: Env | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* Post-init environment — lintrk is a spy-able no-op function carrying the
|
|
101
|
+
* queue shape the real script installs. Tests clone this and replace
|
|
102
|
+
* `window.lintrk` with a jest.fn() before pushing events, so every call is
|
|
103
|
+
* captured.
|
|
104
|
+
*/
|
|
105
|
+
declare const push: Env;
|
|
106
|
+
/**
|
|
107
|
+
* Simulation tracking paths — used by CLI `--simulate` to record which
|
|
108
|
+
* function calls happened during an event push.
|
|
109
|
+
*/
|
|
110
|
+
declare const simulation: string[];
|
|
111
|
+
|
|
112
|
+
declare const env_init: typeof init;
|
|
113
|
+
declare const env_push: typeof push;
|
|
114
|
+
declare const env_simulation: typeof simulation;
|
|
115
|
+
declare namespace env {
|
|
116
|
+
export { env_init as init, env_push as push, env_simulation as simulation };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Examples may optionally override destination-level settings for a test.
|
|
121
|
+
* The test runner reads `settings` from the example and merges it into the
|
|
122
|
+
* base destination settings (on top of the fixed `apiKey`). Rarely needed
|
|
123
|
+
* for LinkedIn — conversion config lives on the rule, not destination-level.
|
|
124
|
+
*/
|
|
125
|
+
type LinkedInStepExample = Flow.StepExample & {
|
|
126
|
+
settings?: Partial<Settings>;
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* OPT-IN: Unmapped event is silently ignored.
|
|
130
|
+
*
|
|
131
|
+
* LinkedIn's core behavioral difference from analytics destinations: events
|
|
132
|
+
* without `mapping.settings.conversion` produce ZERO lintrk() calls. The
|
|
133
|
+
* destination is opt-in — each conversion must reference a pre-created
|
|
134
|
+
* Conversion Rule from Campaign Manager.
|
|
135
|
+
*/
|
|
136
|
+
declare const unmappedEventIgnored: LinkedInStepExample;
|
|
137
|
+
/**
|
|
138
|
+
* Simplest possible conversion — just a `conversion_id` from Campaign Manager.
|
|
139
|
+
*
|
|
140
|
+
* Form submission → LinkedIn Lead conversion. The mapping resolves `id` as a
|
|
141
|
+
* literal value (no walker event field needed). The destination translates
|
|
142
|
+
* `{ id }` → `lintrk('track', { conversion_id })`.
|
|
143
|
+
*/
|
|
144
|
+
declare const simpleConversionId: LinkedInStepExample;
|
|
145
|
+
/**
|
|
146
|
+
* Full e-commerce conversion — every supported lintrk field populated.
|
|
147
|
+
*
|
|
148
|
+
* mapping config uses short walkerOS keys (`id`, `value`, `currency`, `eventId`);
|
|
149
|
+
* the destination translates them to the vendor parameter names
|
|
150
|
+
* (`conversion_id`, `conversion_value`, `currency`, `event_id`).
|
|
151
|
+
*
|
|
152
|
+
* Currency uses the walkerOS fallback syntax: `{ key, value }` — pull from
|
|
153
|
+
* `data.currency` first, fall back to `"EUR"` if absent. The default
|
|
154
|
+
* `order complete` fixture from `getEvent` already sets `data.currency: "EUR"`,
|
|
155
|
+
* so the resolved value is "EUR" here.
|
|
156
|
+
*
|
|
157
|
+
* `eventId` maps from the walkerOS event.id — stable per event, unique, and
|
|
158
|
+
* ready for deduplication with a future server (Conversions API) destination.
|
|
159
|
+
*/
|
|
160
|
+
declare const orderCompleteFullConversion: LinkedInStepExample;
|
|
161
|
+
/**
|
|
162
|
+
* Page view as an explicit conversion.
|
|
163
|
+
*
|
|
164
|
+
* LinkedIn's Insight Tag automatically fires a page view on load for
|
|
165
|
+
* retargeting / audience building — that call is NOT something the
|
|
166
|
+
* destination controls. This example tests the OTHER case: mapping a
|
|
167
|
+
* specific walkerOS `page view` event to a Campaign Manager KEY_PAGE_VIEW
|
|
168
|
+
* conversion rule, which fires an EXPLICIT lintrk('track') call in addition
|
|
169
|
+
* to the auto page view.
|
|
170
|
+
*/
|
|
171
|
+
declare const pageViewConversion: LinkedInStepExample;
|
|
172
|
+
/**
|
|
173
|
+
* Middle-funnel LEAD conversion — demo request without monetary value.
|
|
174
|
+
*
|
|
175
|
+
* LinkedIn's conversion types include LEAD, CONTACT, SIGN_UP, etc. The
|
|
176
|
+
* destination is agnostic to the type (set in Campaign Manager, not at call
|
|
177
|
+
* time) — all we forward is the conversion_id. This fixture exercises the
|
|
178
|
+
* "id + eventId only" shape.
|
|
179
|
+
*/
|
|
180
|
+
declare const demoRequestLead: LinkedInStepExample;
|
|
181
|
+
/**
|
|
182
|
+
* rule.skip — fully-configured conversion rule temporarily disabled.
|
|
183
|
+
*
|
|
184
|
+
* The rule has a valid `conversion.map` but `skip: true` tells the destination
|
|
185
|
+
* to produce zero calls. This is distinct from the opt-in default (no
|
|
186
|
+
* `conversion` at all): skip explicitly keeps the rule on disk for quick
|
|
187
|
+
* reactivation without deleting it.
|
|
188
|
+
*/
|
|
189
|
+
declare const conversionSkipped: LinkedInStepExample;
|
|
190
|
+
/**
|
|
191
|
+
* Falsy `id` → entire lintrk call is skipped.
|
|
192
|
+
*
|
|
193
|
+
* If the resolved conversion object has no truthy `id`, the destination does
|
|
194
|
+
* NOT call lintrk at all. This protects against misconfigured mappings
|
|
195
|
+
* (e.g. pulling id from a non-existent field).
|
|
196
|
+
*
|
|
197
|
+
* Here we map `id` from `data.nonexistentField` — it resolves to undefined,
|
|
198
|
+
* so zero calls are produced.
|
|
199
|
+
*/
|
|
200
|
+
declare const missingConversionIdIgnored: LinkedInStepExample;
|
|
201
|
+
/**
|
|
202
|
+
* Partial conversion — value missing → omitted from the lintrk call.
|
|
203
|
+
*
|
|
204
|
+
* The rule asks for `value: 'data.missingTotal'` (undefined), `currency`
|
|
205
|
+
* (undefined), and `eventId: 'id'` (present). Only `conversion_id` and
|
|
206
|
+
* `event_id` appear in the final call — no `conversion_value`, no `currency`.
|
|
207
|
+
*/
|
|
208
|
+
declare const partialFieldsOmitted: LinkedInStepExample;
|
|
209
|
+
|
|
210
|
+
type step_LinkedInStepExample = LinkedInStepExample;
|
|
211
|
+
declare const step_conversionSkipped: typeof conversionSkipped;
|
|
212
|
+
declare const step_demoRequestLead: typeof demoRequestLead;
|
|
213
|
+
declare const step_missingConversionIdIgnored: typeof missingConversionIdIgnored;
|
|
214
|
+
declare const step_orderCompleteFullConversion: typeof orderCompleteFullConversion;
|
|
215
|
+
declare const step_pageViewConversion: typeof pageViewConversion;
|
|
216
|
+
declare const step_partialFieldsOmitted: typeof partialFieldsOmitted;
|
|
217
|
+
declare const step_simpleConversionId: typeof simpleConversionId;
|
|
218
|
+
declare const step_unmappedEventIgnored: typeof unmappedEventIgnored;
|
|
219
|
+
declare namespace step {
|
|
220
|
+
export { type step_LinkedInStepExample as LinkedInStepExample, step_conversionSkipped as conversionSkipped, step_demoRequestLead as demoRequestLead, step_missingConversionIdIgnored as missingConversionIdIgnored, step_orderCompleteFullConversion as orderCompleteFullConversion, step_pageViewConversion as pageViewConversion, step_partialFieldsOmitted as partialFieldsOmitted, step_simpleConversionId as simpleConversionId, step_unmappedEventIgnored as unmappedEventIgnored };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
declare const index_env: typeof env;
|
|
224
|
+
declare const index_step: typeof step;
|
|
225
|
+
declare namespace index {
|
|
226
|
+
export { index_env as env, index_step as step };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export { index as examples, index$1 as schemas };
|
package/dist/dev.d.ts
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import * as _walkeros_core_dev from '@walkeros/core/dev';
|
|
2
|
+
import { z } from '@walkeros/core/dev';
|
|
3
|
+
import { DestinationWeb } from '@walkeros/web-core';
|
|
4
|
+
import { Flow } from '@walkeros/core';
|
|
5
|
+
|
|
6
|
+
declare const SettingsSchema: z.ZodObject<{
|
|
7
|
+
apiKey: z.ZodString;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
type Settings$1 = z.infer<typeof SettingsSchema>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* LinkedIn per-rule mapping schema.
|
|
13
|
+
*
|
|
14
|
+
* Every field on `conversion` is a walkerOS mapping value (static literal,
|
|
15
|
+
* string path, or `{ map, value, key, fn, ... }` object). The schema uses
|
|
16
|
+
* `z.unknown()` for each so users can supply any valid mapping shape — the
|
|
17
|
+
* destination resolves it via `getMappingValue()` at push time.
|
|
18
|
+
*/
|
|
19
|
+
declare const MappingSchema: z.ZodObject<{
|
|
20
|
+
conversion: z.ZodOptional<z.ZodUnknown>;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
type Mapping = z.infer<typeof MappingSchema>;
|
|
23
|
+
|
|
24
|
+
declare const settings: _walkeros_core_dev.JSONSchema;
|
|
25
|
+
declare const mapping: _walkeros_core_dev.JSONSchema;
|
|
26
|
+
|
|
27
|
+
type index$1_Mapping = Mapping;
|
|
28
|
+
declare const index$1_MappingSchema: typeof MappingSchema;
|
|
29
|
+
declare const index$1_SettingsSchema: typeof SettingsSchema;
|
|
30
|
+
declare const index$1_mapping: typeof mapping;
|
|
31
|
+
declare const index$1_settings: typeof settings;
|
|
32
|
+
declare namespace index$1 {
|
|
33
|
+
export { type index$1_Mapping as Mapping, index$1_MappingSchema as MappingSchema, type Settings$1 as Settings, index$1_SettingsSchema as SettingsSchema, index$1_mapping as mapping, index$1_settings as settings };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* LinkedIn Insight Tag runtime surface.
|
|
38
|
+
*
|
|
39
|
+
* The Insight Tag script installs `window.lintrk` — a single function that
|
|
40
|
+
* accepts exactly one tracked action: `lintrk('track', data)`.
|
|
41
|
+
*
|
|
42
|
+
* Before the script loads, the destination installs a queue-backed shim so
|
|
43
|
+
* calls made during init are buffered and flushed once the script loads.
|
|
44
|
+
* This mirrors the pattern LinkedIn's own snippet uses.
|
|
45
|
+
*/
|
|
46
|
+
type LintrkAction = 'track';
|
|
47
|
+
interface LintrkTrackData {
|
|
48
|
+
conversion_id: number;
|
|
49
|
+
conversion_value?: number;
|
|
50
|
+
currency?: string;
|
|
51
|
+
event_id?: string;
|
|
52
|
+
}
|
|
53
|
+
type Lintrk = ((action: LintrkAction, data: LintrkTrackData) => void) & {
|
|
54
|
+
/** Internal queue populated before the CDN script loads. */
|
|
55
|
+
q?: unknown[];
|
|
56
|
+
};
|
|
57
|
+
declare global {
|
|
58
|
+
interface Window {
|
|
59
|
+
_linkedin_partner_id?: string;
|
|
60
|
+
_linkedin_data_partner_ids?: string[];
|
|
61
|
+
lintrk?: Lintrk;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Destination-level settings.
|
|
66
|
+
*
|
|
67
|
+
* apiKey — the LinkedIn Partner ID (numeric string, e.g. "123456"), assigned
|
|
68
|
+
* to `window._linkedin_partner_id` before the script loads.
|
|
69
|
+
* include — event sections made available for mapping resolution. Present for
|
|
70
|
+
* consistency with other destinations; has no effect at call time
|
|
71
|
+
* because `lintrk()` only accepts four fixed fields. Kept so users
|
|
72
|
+
* can reference section-prefixed keys in future custom mapping
|
|
73
|
+
* strategies without a breaking change.
|
|
74
|
+
*/
|
|
75
|
+
interface Settings {
|
|
76
|
+
apiKey: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Env — mock surface for tests and dev. The destination mutates
|
|
80
|
+
* `window._linkedin_partner_id` / `window._linkedin_data_partner_ids` and
|
|
81
|
+
* installs `window.lintrk` in init; tests can pre-seed `window.lintrk` with
|
|
82
|
+
* a spy to skip the script injection path.
|
|
83
|
+
*
|
|
84
|
+
* `document` is also mocked so `addScript()` can run headlessly.
|
|
85
|
+
*/
|
|
86
|
+
interface Env extends DestinationWeb.Env {
|
|
87
|
+
window: {
|
|
88
|
+
_linkedin_partner_id?: string;
|
|
89
|
+
_linkedin_data_partner_ids?: string[];
|
|
90
|
+
lintrk?: Lintrk;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Pre-init environment — no LinkedIn state present. The destination's init
|
|
96
|
+
* will populate _linkedin_partner_id and install the lintrk queue.
|
|
97
|
+
*/
|
|
98
|
+
declare const init: Env | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* Post-init environment — lintrk is a spy-able no-op function carrying the
|
|
101
|
+
* queue shape the real script installs. Tests clone this and replace
|
|
102
|
+
* `window.lintrk` with a jest.fn() before pushing events, so every call is
|
|
103
|
+
* captured.
|
|
104
|
+
*/
|
|
105
|
+
declare const push: Env;
|
|
106
|
+
/**
|
|
107
|
+
* Simulation tracking paths — used by CLI `--simulate` to record which
|
|
108
|
+
* function calls happened during an event push.
|
|
109
|
+
*/
|
|
110
|
+
declare const simulation: string[];
|
|
111
|
+
|
|
112
|
+
declare const env_init: typeof init;
|
|
113
|
+
declare const env_push: typeof push;
|
|
114
|
+
declare const env_simulation: typeof simulation;
|
|
115
|
+
declare namespace env {
|
|
116
|
+
export { env_init as init, env_push as push, env_simulation as simulation };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Examples may optionally override destination-level settings for a test.
|
|
121
|
+
* The test runner reads `settings` from the example and merges it into the
|
|
122
|
+
* base destination settings (on top of the fixed `apiKey`). Rarely needed
|
|
123
|
+
* for LinkedIn — conversion config lives on the rule, not destination-level.
|
|
124
|
+
*/
|
|
125
|
+
type LinkedInStepExample = Flow.StepExample & {
|
|
126
|
+
settings?: Partial<Settings>;
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* OPT-IN: Unmapped event is silently ignored.
|
|
130
|
+
*
|
|
131
|
+
* LinkedIn's core behavioral difference from analytics destinations: events
|
|
132
|
+
* without `mapping.settings.conversion` produce ZERO lintrk() calls. The
|
|
133
|
+
* destination is opt-in — each conversion must reference a pre-created
|
|
134
|
+
* Conversion Rule from Campaign Manager.
|
|
135
|
+
*/
|
|
136
|
+
declare const unmappedEventIgnored: LinkedInStepExample;
|
|
137
|
+
/**
|
|
138
|
+
* Simplest possible conversion — just a `conversion_id` from Campaign Manager.
|
|
139
|
+
*
|
|
140
|
+
* Form submission → LinkedIn Lead conversion. The mapping resolves `id` as a
|
|
141
|
+
* literal value (no walker event field needed). The destination translates
|
|
142
|
+
* `{ id }` → `lintrk('track', { conversion_id })`.
|
|
143
|
+
*/
|
|
144
|
+
declare const simpleConversionId: LinkedInStepExample;
|
|
145
|
+
/**
|
|
146
|
+
* Full e-commerce conversion — every supported lintrk field populated.
|
|
147
|
+
*
|
|
148
|
+
* mapping config uses short walkerOS keys (`id`, `value`, `currency`, `eventId`);
|
|
149
|
+
* the destination translates them to the vendor parameter names
|
|
150
|
+
* (`conversion_id`, `conversion_value`, `currency`, `event_id`).
|
|
151
|
+
*
|
|
152
|
+
* Currency uses the walkerOS fallback syntax: `{ key, value }` — pull from
|
|
153
|
+
* `data.currency` first, fall back to `"EUR"` if absent. The default
|
|
154
|
+
* `order complete` fixture from `getEvent` already sets `data.currency: "EUR"`,
|
|
155
|
+
* so the resolved value is "EUR" here.
|
|
156
|
+
*
|
|
157
|
+
* `eventId` maps from the walkerOS event.id — stable per event, unique, and
|
|
158
|
+
* ready for deduplication with a future server (Conversions API) destination.
|
|
159
|
+
*/
|
|
160
|
+
declare const orderCompleteFullConversion: LinkedInStepExample;
|
|
161
|
+
/**
|
|
162
|
+
* Page view as an explicit conversion.
|
|
163
|
+
*
|
|
164
|
+
* LinkedIn's Insight Tag automatically fires a page view on load for
|
|
165
|
+
* retargeting / audience building — that call is NOT something the
|
|
166
|
+
* destination controls. This example tests the OTHER case: mapping a
|
|
167
|
+
* specific walkerOS `page view` event to a Campaign Manager KEY_PAGE_VIEW
|
|
168
|
+
* conversion rule, which fires an EXPLICIT lintrk('track') call in addition
|
|
169
|
+
* to the auto page view.
|
|
170
|
+
*/
|
|
171
|
+
declare const pageViewConversion: LinkedInStepExample;
|
|
172
|
+
/**
|
|
173
|
+
* Middle-funnel LEAD conversion — demo request without monetary value.
|
|
174
|
+
*
|
|
175
|
+
* LinkedIn's conversion types include LEAD, CONTACT, SIGN_UP, etc. The
|
|
176
|
+
* destination is agnostic to the type (set in Campaign Manager, not at call
|
|
177
|
+
* time) — all we forward is the conversion_id. This fixture exercises the
|
|
178
|
+
* "id + eventId only" shape.
|
|
179
|
+
*/
|
|
180
|
+
declare const demoRequestLead: LinkedInStepExample;
|
|
181
|
+
/**
|
|
182
|
+
* rule.skip — fully-configured conversion rule temporarily disabled.
|
|
183
|
+
*
|
|
184
|
+
* The rule has a valid `conversion.map` but `skip: true` tells the destination
|
|
185
|
+
* to produce zero calls. This is distinct from the opt-in default (no
|
|
186
|
+
* `conversion` at all): skip explicitly keeps the rule on disk for quick
|
|
187
|
+
* reactivation without deleting it.
|
|
188
|
+
*/
|
|
189
|
+
declare const conversionSkipped: LinkedInStepExample;
|
|
190
|
+
/**
|
|
191
|
+
* Falsy `id` → entire lintrk call is skipped.
|
|
192
|
+
*
|
|
193
|
+
* If the resolved conversion object has no truthy `id`, the destination does
|
|
194
|
+
* NOT call lintrk at all. This protects against misconfigured mappings
|
|
195
|
+
* (e.g. pulling id from a non-existent field).
|
|
196
|
+
*
|
|
197
|
+
* Here we map `id` from `data.nonexistentField` — it resolves to undefined,
|
|
198
|
+
* so zero calls are produced.
|
|
199
|
+
*/
|
|
200
|
+
declare const missingConversionIdIgnored: LinkedInStepExample;
|
|
201
|
+
/**
|
|
202
|
+
* Partial conversion — value missing → omitted from the lintrk call.
|
|
203
|
+
*
|
|
204
|
+
* The rule asks for `value: 'data.missingTotal'` (undefined), `currency`
|
|
205
|
+
* (undefined), and `eventId: 'id'` (present). Only `conversion_id` and
|
|
206
|
+
* `event_id` appear in the final call — no `conversion_value`, no `currency`.
|
|
207
|
+
*/
|
|
208
|
+
declare const partialFieldsOmitted: LinkedInStepExample;
|
|
209
|
+
|
|
210
|
+
type step_LinkedInStepExample = LinkedInStepExample;
|
|
211
|
+
declare const step_conversionSkipped: typeof conversionSkipped;
|
|
212
|
+
declare const step_demoRequestLead: typeof demoRequestLead;
|
|
213
|
+
declare const step_missingConversionIdIgnored: typeof missingConversionIdIgnored;
|
|
214
|
+
declare const step_orderCompleteFullConversion: typeof orderCompleteFullConversion;
|
|
215
|
+
declare const step_pageViewConversion: typeof pageViewConversion;
|
|
216
|
+
declare const step_partialFieldsOmitted: typeof partialFieldsOmitted;
|
|
217
|
+
declare const step_simpleConversionId: typeof simpleConversionId;
|
|
218
|
+
declare const step_unmappedEventIgnored: typeof unmappedEventIgnored;
|
|
219
|
+
declare namespace step {
|
|
220
|
+
export { type step_LinkedInStepExample as LinkedInStepExample, step_conversionSkipped as conversionSkipped, step_demoRequestLead as demoRequestLead, step_missingConversionIdIgnored as missingConversionIdIgnored, step_orderCompleteFullConversion as orderCompleteFullConversion, step_pageViewConversion as pageViewConversion, step_partialFieldsOmitted as partialFieldsOmitted, step_simpleConversionId as simpleConversionId, step_unmappedEventIgnored as unmappedEventIgnored };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
declare const index_env: typeof env;
|
|
224
|
+
declare const index_step: typeof step;
|
|
225
|
+
declare namespace index {
|
|
226
|
+
export { index_env as env, index_step as step };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export { index as examples, index$1 as schemas };
|