@walkeros/web-destination-amplitude 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 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,273 @@
1
+ <p align="left">
2
+ <a href="https://www.walkeros.io">
3
+ <img alt="walkerOS" title="walkerOS" src="https://www.walkeros.io/img/walkerOS_logo.svg" width="256px"/>
4
+ </a>
5
+ </p>
6
+
7
+ # Amplitude Destination for walkerOS
8
+
9
+ [Source Code](https://github.com/elbwalker/walkerOS/tree/main/packages/web/destinations/amplitude)
10
+ &bull;
11
+ [NPM Package](https://www.npmjs.com/package/@walkeros/web-destination-amplitude)
12
+ &bull; [Documentation](https://www.walkeros.io/docs/destinations/web/amplitude)
13
+
14
+ This package forwards walkerOS events to [Amplitude](https://amplitude.com/) —
15
+ product analytics with identity, revenue, groups, and optional session replay,
16
+ experiments, and guides & surveys. Built on the official
17
+ [`@amplitude/unified`](https://www.npmjs.com/package/@amplitude/unified) SDK
18
+ which bundles analytics, session replay, experiments, and engagement.
19
+
20
+ walkerOS follows a **source → collector → destination** architecture. This
21
+ Amplitude destination receives processed events from the walkerOS collector and
22
+ forwards them as Amplitude track, identify, revenue, group, and consent calls.
23
+
24
+ ## Features
25
+
26
+ - **Default event forwarding** — every walkerOS event becomes
27
+ `amplitude.track(name, event_properties)` with no additional config
28
+ - **Custom event properties** — flatten walkerOS event sections
29
+ (`settings.include`) or map freely via the standard walkerOS `mapping.data`
30
+ DSL
31
+ - **Identity** — destination-level and per-event `settings.identify` with the
32
+ full Amplitude operation vocabulary (`set`, `setOnce`, `add`, `append`,
33
+ `prepend`, `preInsert`, `postInsert`, `remove`, `unset`, `clearAll`). Runtime
34
+ state diffing skips redundant setter calls.
35
+ - **Revenue** — `settings.revenue` supports both single-object and `loop`-based
36
+ multi-product orders. Currency defaults to `"EUR"`.
37
+ - **Groups** — `settings.group` and `settings.groupIdentify` for B2B flows
38
+ - **Consent** — `on('consent')` handler derives the consent keys from
39
+ `config.consent` and toggles `amplitude.setOptOut()`
40
+ - **Optional plugins** (all npm-bundled via `@amplitude/unified`, opt-in via
41
+ settings): Session Replay, Feature Experiments, Engagement (Guides & Surveys)
42
+ - **Async init** — awaits `amplitude.initAll(...)` so downstream pushes are
43
+ truly ready before returning
44
+
45
+ > **Bundle cost:** All three plugin packages are statically imported and
46
+ > therefore bundled even when not configured. Expect an additional ~135 KB from
47
+ > Session Replay plus the Experiment and Engagement payloads.
48
+
49
+ ## Installation
50
+
51
+ ```sh
52
+ npm install @walkeros/web-destination-amplitude
53
+ ```
54
+
55
+ ## Quick Start
56
+
57
+ ```typescript
58
+ import { startFlow } from '@walkeros/collector';
59
+ import { destinationAmplitude } from '@walkeros/web-destination-amplitude';
60
+
61
+ await startFlow({
62
+ destinations: {
63
+ amplitude: {
64
+ code: destinationAmplitude,
65
+ config: {
66
+ consent: { analytics: true },
67
+ settings: {
68
+ apiKey: 'YOUR_AMPLITUDE_API_KEY',
69
+ },
70
+ },
71
+ },
72
+ },
73
+ });
74
+ ```
75
+
76
+ ## Configuration
77
+
78
+ ### Settings (destination-level)
79
+
80
+ All fields of Amplitude's `BrowserOptions` pass through to
81
+ `amplitude.init(apiKey, options)`. walkerOS-specific additions:
82
+
83
+ | Name | Type | Description | Required |
84
+ | --------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | -------- |
85
+ | `apiKey` | `string` | Your Amplitude project API key | Yes |
86
+ | `identify` | `Mapping.Value` | Destination-level identity mapping; see Identity section | No |
87
+ | `include` | `string[]` | walkerOS event sections to flatten into `event_properties` (`data`, `globals`, `context`, `user`, `source`, `version`, `event`, or `all`) | No |
88
+ | `sessionReplay` | `SessionReplayOptions` | If set, enables session replay via `@amplitude/unified` with these options | No |
89
+ | `experiment` | `ExperimentConfig` + `deploymentKey` | If `deploymentKey` set, configures the experiment plugin from `@amplitude/unified` | No |
90
+ | `engagement` | `boolean \| InitOptions` | Pass `true` for default Guides & Surveys plugin, or an options object | No |
91
+
92
+ ### Mapping (`rule.settings`)
93
+
94
+ | Name | Type | Description |
95
+ | --------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
96
+ | `identify` | `Mapping.Value` | Per-event identity; resolves to an object with any of `user`, `device`, `session`, `set`, `setOnce`, `add`, `append`, `prepend`, `preInsert`, `postInsert`, `remove`, `unset`, `clearAll` |
97
+ | `include` | `string[]` | Overrides destination-level `include` for this rule |
98
+ | `revenue` | `Mapping.Value` | Resolves to a single object or (via `loop`) an array, each with `productId`, `price`, `quantity`, `revenueType`, `currency`, `revenue`, `receipt`, `receiptSig`, `eventProperties`. One `amplitude.revenue()` call fires per item. |
99
+ | `group` | `Mapping.Value` | Resolves to `{ type, name }` → `amplitude.setGroup(type, name)` |
100
+ | `groupIdentify` | `Mapping.Value` | Resolves to `{ type, name, set?, setOnce?, ... }` → `amplitude.groupIdentify(type, name, identify)` |
101
+ | `reset` | `boolean \| Mapping.Value` | Truthy → `amplitude.reset()` (logout). Typically paired with `skip: true`. |
102
+
103
+ ## Custom Event Properties
104
+
105
+ ```typescript
106
+ // Flatten walkerOS sections onto every tracked event (prefixed).
107
+ settings: {
108
+ apiKey: 'YOUR_KEY',
109
+ include: ['data', 'globals'],
110
+ }
111
+ // → amplitude.track('product view', { data_id: 'ers', data_price: 420, globals_pagegroup: 'shop' })
112
+ ```
113
+
114
+ Per-rule override via `mapping.settings.include` replaces destination-level
115
+ `include` for the matched rule.
116
+
117
+ ## Identity
118
+
119
+ ```typescript
120
+ mapping: {
121
+ user: {
122
+ login: {
123
+ skip: true, // suppress default track()
124
+ settings: {
125
+ identify: {
126
+ map: {
127
+ user: 'data.user_id',
128
+ set: { map: { plan: 'data.plan', email: 'data.email' } },
129
+ setOnce: { map: { first_login: 'timestamp' } },
130
+ add: { map: { login_count: { value: 1 } } },
131
+ },
132
+ },
133
+ },
134
+ },
135
+ },
136
+ }
137
+ ```
138
+
139
+ - `user` → `amplitude.setUserId(...)` (with state diffing)
140
+ - `device` → `amplitude.setDeviceId(...)`
141
+ - `session` → `amplitude.setSessionId(...)` (numeric strings parse; other
142
+ strings are deterministically hashed via djb2 for cross-page-load consistency)
143
+ - The remaining operation keys are forwarded through `amplitude.Identify` and
144
+ `amplitude.identify(...)`
145
+
146
+ ## Revenue
147
+
148
+ ```typescript
149
+ // Single-product renewal
150
+ mapping: {
151
+ subscription: {
152
+ renew: {
153
+ skip: true,
154
+ settings: {
155
+ revenue: {
156
+ map: {
157
+ productId: 'data.plan_id',
158
+ price: 'data.amount',
159
+ revenueType: { value: 'renewal' },
160
+ currency: { key: 'data.currency', value: 'EUR' },
161
+ },
162
+ },
163
+ },
164
+ },
165
+ },
166
+ }
167
+
168
+ // Multi-product order via loop
169
+ mapping: {
170
+ order: {
171
+ complete: {
172
+ settings: {
173
+ include: ['data'],
174
+ revenue: {
175
+ loop: ['nested', {
176
+ condition: (v) => typeof v?.data?.price === 'number',
177
+ map: {
178
+ productId: 'data.id',
179
+ price: 'data.price',
180
+ quantity: { key: 'data.quantity', value: 1 },
181
+ revenueType: { value: 'purchase' },
182
+ currency: { key: 'data.currency', value: 'EUR' },
183
+ },
184
+ }],
185
+ },
186
+ },
187
+ },
188
+ },
189
+ }
190
+ ```
191
+
192
+ Every item from the loop becomes its own `amplitude.revenue()` call; the default
193
+ `track()` still fires once for the order-level event.
194
+
195
+ ## Groups
196
+
197
+ ```typescript
198
+ settings: {
199
+ group: {
200
+ map: { type: { value: 'company' }, name: 'data.company' },
201
+ },
202
+ groupIdentify: {
203
+ map: {
204
+ type: { value: 'company' },
205
+ name: 'data.company',
206
+ set: { map: { industry: 'data.industry' } },
207
+ },
208
+ },
209
+ }
210
+ // → amplitude.setGroup('company', 'Acme')
211
+ // → amplitude.groupIdentify('company', 'Acme', identify)
212
+ ```
213
+
214
+ ## Reset (Logout)
215
+
216
+ ```typescript
217
+ mapping: {
218
+ user: {
219
+ logout: {
220
+ skip: true,
221
+ settings: { reset: true },
222
+ },
223
+ },
224
+ }
225
+ // → amplitude.reset()
226
+ ```
227
+
228
+ Clears the Amplitude user ID and regenerates a device ID. The destination also
229
+ clears its runtime identity cache so the next push re-fires the setters.
230
+
231
+ ## Consent
232
+
233
+ Declare the required consent keys on the destination config, then push a walker
234
+ consent event — the destination's `on('consent')` handler toggles
235
+ `amplitude.setOptOut()` accordingly. Semantics are strict: all required keys
236
+ must be granted for opt-in; any missing grant opts out.
237
+
238
+ ```typescript
239
+ config: {
240
+ consent: { analytics: true }, // required consent keys
241
+ settings: { apiKey: 'YOUR_KEY' },
242
+ }
243
+ // elb('walker consent', { analytics: false }) → amplitude.setOptOut(true)
244
+ // elb('walker consent', { analytics: true }) → amplitude.setOptOut(false)
245
+ ```
246
+
247
+ ## Plugins
248
+
249
+ All three plugins are bundled via `@amplitude/unified` and opt-in via
250
+ destination settings:
251
+
252
+ ```typescript
253
+ settings: {
254
+ apiKey: 'YOUR_KEY',
255
+
256
+ // Session Replay
257
+ sessionReplay: { sampleRate: 1 },
258
+
259
+ // Feature Experiments (via @amplitude/unified)
260
+ experiment: { deploymentKey: 'DEPLOYMENT_KEY' },
261
+
262
+ // Guides & Surveys (true for defaults, object for custom)
263
+ engagement: true,
264
+ }
265
+ ```
266
+
267
+ ## Related
268
+
269
+ - [walkerOS documentation](https://www.walkeros.io/docs)
270
+ - [Amplitude Browser SDK docs](https://amplitude.com/docs/sdks/analytics/browser/browser-sdk-2)
271
+ - [Amplitude Session Replay](https://amplitude.com/docs/session-replay)
272
+ - [Amplitude Experiment](https://amplitude.com/docs/experiment)
273
+ - [Amplitude Guides & Surveys](https://amplitude.com/docs/guides-and-surveys)
package/dist/dev.d.mts ADDED
@@ -0,0 +1,289 @@
1
+ import * as _walkeros_core_dev from '@walkeros/core/dev';
2
+ import { z } from '@walkeros/core/dev';
3
+ import { Mapping as Mapping$1, Flow } from '@walkeros/core';
4
+ import { DestinationWeb } from '@walkeros/web-core';
5
+ import { Types } from '@amplitude/unified';
6
+ import { SessionReplayOptions } from '@amplitude/plugin-session-replay-browser';
7
+ import { ExperimentPluginConfig } from '@amplitude/plugin-experiment-browser';
8
+ import { InitOptions } from '@amplitude/engagement-browser';
9
+
10
+ declare const SettingsSchema: z.ZodObject<{
11
+ apiKey: z.ZodString;
12
+ serverZone: z.ZodOptional<z.ZodEnum<{
13
+ US: "US";
14
+ EU: "EU";
15
+ }>>;
16
+ flushIntervalMillis: z.ZodOptional<z.ZodNumber>;
17
+ flushQueueSize: z.ZodOptional<z.ZodNumber>;
18
+ flushMaxRetries: z.ZodOptional<z.ZodNumber>;
19
+ transport: z.ZodOptional<z.ZodEnum<{
20
+ fetch: "fetch";
21
+ xhr: "xhr";
22
+ beacon: "beacon";
23
+ }>>;
24
+ useBatch: z.ZodOptional<z.ZodBoolean>;
25
+ appVersion: z.ZodOptional<z.ZodString>;
26
+ identify: z.ZodOptional<z.ZodUnknown>;
27
+ sessionReplay: z.ZodOptional<z.ZodUnknown>;
28
+ experiment: z.ZodOptional<z.ZodUnknown>;
29
+ engagement: z.ZodOptional<z.ZodUnknown>;
30
+ }, z.core.$strip>;
31
+ type Settings$1 = z.infer<typeof SettingsSchema>;
32
+
33
+ declare const MappingSchema: z.ZodObject<{
34
+ identify: z.ZodOptional<z.ZodUnknown>;
35
+ revenue: z.ZodOptional<z.ZodUnknown>;
36
+ group: z.ZodOptional<z.ZodUnknown>;
37
+ groupIdentify: z.ZodOptional<z.ZodUnknown>;
38
+ reset: z.ZodOptional<z.ZodUnknown>;
39
+ }, z.core.$strip>;
40
+ type Mapping = z.infer<typeof MappingSchema>;
41
+
42
+ declare const settings: _walkeros_core_dev.JSONSchema;
43
+ declare const mapping: _walkeros_core_dev.JSONSchema;
44
+
45
+ type index$1_Mapping = Mapping;
46
+ declare const index$1_MappingSchema: typeof MappingSchema;
47
+ declare const index$1_SettingsSchema: typeof SettingsSchema;
48
+ declare const index$1_mapping: typeof mapping;
49
+ declare const index$1_settings: typeof settings;
50
+ declare namespace index$1 {
51
+ 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 };
52
+ }
53
+
54
+ type BrowserOptions = Omit<Types.BrowserOptions, 'identify'>;
55
+ /**
56
+ * Destination-level settings.
57
+ *
58
+ * All Amplitude `BrowserOptions` are passthrough init options — extending the
59
+ * SDK type directly keeps IntelliSense complete and prevents drift. The
60
+ * destination adds:
61
+ * - `apiKey` (required) — first arg to `amplitude.init(...)`
62
+ * - `identify` — destination-level identity mapping
63
+ * - `sessionReplay` / `experiment` / `engagement` — optional plugin configs
64
+ * - `_state` — runtime state (not user-facing, mutated by init/push)
65
+ */
66
+ interface Settings extends BrowserOptions {
67
+ apiKey: string;
68
+ identify?: Mapping$1.Value;
69
+ sessionReplay?: SessionReplayOptions;
70
+ experiment?: ExperimentPluginConfig & {
71
+ deploymentKey: string;
72
+ };
73
+ engagement?: boolean | InitOptions;
74
+ /** Runtime state — populated by init() and mutated by push(). Not user-facing. */
75
+ _state?: RuntimeState;
76
+ }
77
+ interface RuntimeState {
78
+ /** Last-set identity values, used to skip redundant setUserId/setDeviceId/setSessionId calls. */
79
+ lastIdentity?: {
80
+ user?: string;
81
+ device?: string;
82
+ session?: number;
83
+ };
84
+ }
85
+ /**
86
+ * Amplitude SDK surface — the subset of @amplitude/unified the
87
+ * destination actually uses. Mirrors the real module's named exports so
88
+ * tests can mock each method individually via env.amplitude.
89
+ */
90
+ interface AmplitudeSDK {
91
+ initAll: (apiKey: string, options?: Record<string, unknown>) => Promise<void>;
92
+ track: (eventType: string, eventProperties?: Record<string, unknown>) => void;
93
+ identify: (identify: IdentifyInstance) => void;
94
+ revenue: (revenue: RevenueInstance) => void;
95
+ reset: () => void;
96
+ setOptOut: (optOut: boolean) => void;
97
+ setUserId: (userId: string | undefined) => void;
98
+ setDeviceId: (deviceId: string) => void;
99
+ setSessionId: (sessionId: number) => void;
100
+ setGroup: (groupType: string, groupName: string | string[]) => void;
101
+ groupIdentify: (groupType: string, groupName: string, identify: IdentifyInstance) => void;
102
+ flush: () => {
103
+ promise: Promise<void>;
104
+ };
105
+ add: (plugin: unknown) => {
106
+ promise: Promise<void>;
107
+ };
108
+ Identify: new () => IdentifyInstance;
109
+ Revenue: new () => RevenueInstance;
110
+ }
111
+ /** Chainable Identify — mirrors @amplitude/unified Identify class. */
112
+ interface IdentifyInstance {
113
+ set: (property: string, value: unknown) => IdentifyInstance;
114
+ setOnce: (property: string, value: unknown) => IdentifyInstance;
115
+ add: (property: string, value: number) => IdentifyInstance;
116
+ append: (property: string, value: unknown) => IdentifyInstance;
117
+ prepend: (property: string, value: unknown) => IdentifyInstance;
118
+ preInsert: (property: string, value: unknown) => IdentifyInstance;
119
+ postInsert: (property: string, value: unknown) => IdentifyInstance;
120
+ remove: (property: string, value: unknown) => IdentifyInstance;
121
+ unset: (property: string) => IdentifyInstance;
122
+ clearAll: () => IdentifyInstance;
123
+ }
124
+ /** Chainable Revenue — mirrors @amplitude/unified Revenue class. */
125
+ interface RevenueInstance {
126
+ setProductId: (id: string) => RevenueInstance;
127
+ setPrice: (price: number) => RevenueInstance;
128
+ setQuantity: (quantity: number) => RevenueInstance;
129
+ setRevenueType: (type: string) => RevenueInstance;
130
+ setCurrency: (currency: string) => RevenueInstance;
131
+ setRevenue: (revenue: number) => RevenueInstance;
132
+ setReceipt: (receipt: string) => RevenueInstance;
133
+ setReceiptSig: (signature: string) => RevenueInstance;
134
+ setEventProperties: (properties: Record<string, unknown>) => RevenueInstance;
135
+ }
136
+ /**
137
+ * Env — optional SDK override. Production leaves this undefined and the
138
+ * destination falls back to the real @amplitude/unified module
139
+ * import. Tests provide a mock via env.amplitude = { ... }.
140
+ */
141
+ interface Env extends DestinationWeb.Env {
142
+ amplitude?: AmplitudeSDK;
143
+ }
144
+
145
+ /**
146
+ * Pre-init env — all methods are no-ops until the test runner wires spies.
147
+ */
148
+ declare const init: Env | undefined;
149
+ /**
150
+ * Post-init env — same shape. The test runner clones this and replaces
151
+ * individual methods with jest.fn() so it can assert on calls.
152
+ */
153
+ declare const push: Env;
154
+ /** Simulation tracking paths for CLI --simulate. */
155
+ declare const simulation: string[];
156
+
157
+ declare const env_init: typeof init;
158
+ declare const env_push: typeof push;
159
+ declare const env_simulation: typeof simulation;
160
+ declare namespace env {
161
+ export { env_init as init, env_push as push, env_simulation as simulation };
162
+ }
163
+
164
+ /**
165
+ * Examples may optionally carry destination-level settings and/or an
166
+ * `await` hint for async scenarios. The test runner reads `settings`
167
+ * from the example and merges it into the base destination settings
168
+ * on top of the fixed apiKey. `configInclude` is passed as config-level
169
+ * include when registering the destination.
170
+ */
171
+ type AmplitudeStepExample = Flow.StepExample & {
172
+ settings?: Partial<Settings>;
173
+ configInclude?: string[];
174
+ };
175
+ /**
176
+ * Default event forwarding — every walkerOS event becomes
177
+ * amplitude.track(event.name, event_properties). With no mapping and
178
+ * no destination-level include, event_properties is `{}`.
179
+ */
180
+ declare const defaultEventForwarding: AmplitudeStepExample;
181
+ /**
182
+ * Wildcard ignore — walkerOS's standard way to drop events. The rule
183
+ * matches but does nothing. The destination fires zero SDK calls.
184
+ */
185
+ declare const wildcardIgnored: AmplitudeStepExample;
186
+ /**
187
+ * Destination-level settings.include flattens the walkerOS `data` section
188
+ * into prefixed event_properties on every push.
189
+ */
190
+ declare const destinationLevelInclude: AmplitudeStepExample;
191
+ /**
192
+ * Per-rule settings.include REPLACES destination-level include for the
193
+ * matched rule. Here destination-level sends `data`, but the rule
194
+ * overrides it with `globals` only.
195
+ */
196
+ declare const ruleIncludeReplaces: AmplitudeStepExample;
197
+ /**
198
+ * Destination-level settings.identify fires on the first push (once the
199
+ * state cache is empty). The destination sets user/device/session IDs
200
+ * and tracks them in runtime state; subsequent pushes with unchanged
201
+ * values do NOT re-fire the setters.
202
+ *
203
+ * This example represents the first push in a fresh session. user.id,
204
+ * user.device, user.session come from the walkerOS session fixture.
205
+ *
206
+ * The walkerOS fixture's user.session is 's3ss10n' (string). The
207
+ * destination deterministically hashes non-numeric session strings via
208
+ * djb2 so the same walkerOS session always maps to the same Amplitude
209
+ * session number (cross-page-load consistency). djb2('s3ss10n') = 394324160.
210
+ */
211
+ declare const destinationLevelIdentify: AmplitudeStepExample;
212
+ /**
213
+ * Per-event identify with the full operation vocabulary — this is the
214
+ * "user login" pattern: set user_id, enrich user properties. `skip: true`
215
+ * suppresses the default amplitude.track() call because we're running
216
+ * identity side effects only.
217
+ */
218
+ declare const userLoginIdentify: AmplitudeStepExample;
219
+ /**
220
+ * User logout — reset: true fires amplitude.reset(), which clears userId
221
+ * and regenerates deviceId. `skip: true` because we're only running the
222
+ * reset side effect, no default track().
223
+ */
224
+ declare const userLogoutReset: AmplitudeStepExample;
225
+ /**
226
+ * Single-product revenue — resolves `settings.revenue` to one object and
227
+ * fires one amplitude.revenue() call. Note the `{ key: "data.currency",
228
+ * value: "EUR" }` fallback syntax: try data.currency, default to "EUR".
229
+ *
230
+ * The walkerOS default event has no data.currency, so the fallback fires.
231
+ */
232
+ declare const subscriptionRenewRevenue: AmplitudeStepExample;
233
+ /**
234
+ * Multi-product order — the canonical Amplitude ecommerce pattern.
235
+ * `revenue.loop: ["nested", { map: ... }]` iterates event.nested and
236
+ * resolves one revenue item per entry. Each becomes a separate
237
+ * amplitude.revenue() call. The order-level track() fires once with
238
+ * include-based event_properties.
239
+ *
240
+ * The default "order complete" fixture has 3 nested entries: two
241
+ * products (ers, cc) and one gift. Products have `data.price`; the
242
+ * gift has only `data.name`. The `condition` on the loop inner value
243
+ * filters to products only (price must be present).
244
+ */
245
+ declare const orderCompleteMultiProduct: AmplitudeStepExample;
246
+ /**
247
+ * Group assignment + group properties. Typically used for B2B products
248
+ * where a user belongs to a company. Both SDK calls fire on the same rule.
249
+ */
250
+ declare const groupAssignmentWithProperties: AmplitudeStepExample;
251
+ /**
252
+ * Consent revoked → amplitude.setOptOut(true). The destination checks
253
+ * the consent keys declared in config.consent and toggles optOut
254
+ * accordingly (strict: all required keys must be granted).
255
+ *
256
+ * Uses the canonical StepExample.command='consent' pattern: the test
257
+ * runner dispatches via elb('walker consent', in) instead of pushing
258
+ * an event.
259
+ */
260
+ declare const consentRevokeOptOut: AmplitudeStepExample;
261
+ /**
262
+ * Consent granted → amplitude.setOptOut(false).
263
+ */
264
+ declare const consentGrantOptIn: AmplitudeStepExample;
265
+
266
+ type step_AmplitudeStepExample = AmplitudeStepExample;
267
+ declare const step_consentGrantOptIn: typeof consentGrantOptIn;
268
+ declare const step_consentRevokeOptOut: typeof consentRevokeOptOut;
269
+ declare const step_defaultEventForwarding: typeof defaultEventForwarding;
270
+ declare const step_destinationLevelIdentify: typeof destinationLevelIdentify;
271
+ declare const step_destinationLevelInclude: typeof destinationLevelInclude;
272
+ declare const step_groupAssignmentWithProperties: typeof groupAssignmentWithProperties;
273
+ declare const step_orderCompleteMultiProduct: typeof orderCompleteMultiProduct;
274
+ declare const step_ruleIncludeReplaces: typeof ruleIncludeReplaces;
275
+ declare const step_subscriptionRenewRevenue: typeof subscriptionRenewRevenue;
276
+ declare const step_userLoginIdentify: typeof userLoginIdentify;
277
+ declare const step_userLogoutReset: typeof userLogoutReset;
278
+ declare const step_wildcardIgnored: typeof wildcardIgnored;
279
+ declare namespace step {
280
+ export { type step_AmplitudeStepExample as AmplitudeStepExample, step_consentGrantOptIn as consentGrantOptIn, step_consentRevokeOptOut as consentRevokeOptOut, step_defaultEventForwarding as defaultEventForwarding, step_destinationLevelIdentify as destinationLevelIdentify, step_destinationLevelInclude as destinationLevelInclude, step_groupAssignmentWithProperties as groupAssignmentWithProperties, step_orderCompleteMultiProduct as orderCompleteMultiProduct, step_ruleIncludeReplaces as ruleIncludeReplaces, step_subscriptionRenewRevenue as subscriptionRenewRevenue, step_userLoginIdentify as userLoginIdentify, step_userLogoutReset as userLogoutReset, step_wildcardIgnored as wildcardIgnored };
281
+ }
282
+
283
+ declare const index_env: typeof env;
284
+ declare const index_step: typeof step;
285
+ declare namespace index {
286
+ export { index_env as env, index_step as step };
287
+ }
288
+
289
+ export { index as examples, index$1 as schemas };