@walkeros/web-destination-tiktok 4.8.1 → 4.8.2
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 +45 -0
- package/README.md +1 -1
- package/dist/dev.d.mts +26 -8
- package/dist/dev.d.ts +26 -8
- package/dist/dev.js +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/examples/index.d.mts +25 -7
- package/dist/examples/index.d.ts +25 -7
- package/dist/examples/index.js +60 -36
- package/dist/examples/index.mjs +61 -37
- package/dist/index.browser.js +1 -1
- package/dist/index.d.mts +16 -7
- package/dist/index.d.ts +16 -7
- package/dist/index.es5.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/walkerOS.json +107 -23
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# @walkeros/web-destination-tiktok
|
|
2
2
|
|
|
3
|
+
## 4.8.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7e5fc27: A consent handler decides on the whole consent state against the
|
|
8
|
+
destination's own `config.consent` and acts only when a change touches its
|
|
9
|
+
required keys. Optimizely keeps its client across a revoke and a grant,
|
|
10
|
+
instead of closing it.
|
|
11
|
+
- 7e5fc27: A silent rule whose identify, group or similar mapping resolves to
|
|
12
|
+
nothing sends nothing, counts as delivered and writes one DEBUG line naming
|
|
13
|
+
the call and mapping key, never the value. An identity or group that is
|
|
14
|
+
already current writes nothing.
|
|
15
|
+
- 7e5fc27: Settings accept SDK options that the schema does not list and pass
|
|
16
|
+
them through to the SDK, so a newer SDK option no longer fails validation.
|
|
17
|
+
Amplitude events from a setup with plugins no longer carry the
|
|
18
|
+
`amplitude-ts-unified` library prefix.
|
|
19
|
+
- 2374f54: A failed vendor call, a missing required setting (`config`) and an
|
|
20
|
+
event that cannot be sent (`missing-input`) are reported as failed pushes,
|
|
21
|
+
with the dead-letter queue and one ERROR line, instead of counting as
|
|
22
|
+
delivered. Rules with `silent: true` send no event. Settings schemas reject
|
|
23
|
+
unknown keys.
|
|
24
|
+
- b1d65e2: Web destinations that load a vendor script inject it through the
|
|
25
|
+
document of their `env`, so simulation and server-side rendering work without
|
|
26
|
+
a browser page. A page still gets the script in its own document by default,
|
|
27
|
+
and a missing document fails the push with `vendor-not-ready`.
|
|
28
|
+
- 2374f54: Vendor scripts load through walkerOS: a blocked or slow script fails
|
|
29
|
+
later events visibly (`vendor-not-loaded`, `vendor-timeout`) instead of losing
|
|
30
|
+
them. Pushes made while the script loads wait for it, and each script is
|
|
31
|
+
injected once per page.
|
|
32
|
+
- Updated dependencies [2374f54]
|
|
33
|
+
- Updated dependencies [7e5fc27]
|
|
34
|
+
- Updated dependencies [2374f54]
|
|
35
|
+
- Updated dependencies [964590a]
|
|
36
|
+
- Updated dependencies [4100ede]
|
|
37
|
+
- Updated dependencies [2374f54]
|
|
38
|
+
- Updated dependencies [2374f54]
|
|
39
|
+
- Updated dependencies [15eb7b2]
|
|
40
|
+
- Updated dependencies [33a2779]
|
|
41
|
+
- Updated dependencies [33a2779]
|
|
42
|
+
- Updated dependencies [b1d65e2]
|
|
43
|
+
- Updated dependencies [964590a]
|
|
44
|
+
- Updated dependencies [2374f54]
|
|
45
|
+
- @walkeros/core@4.8.2
|
|
46
|
+
- @walkeros/web-core@4.8.2
|
|
47
|
+
|
|
3
48
|
## 4.8.1
|
|
4
49
|
|
|
5
50
|
### Patch Changes
|
package/README.md
CHANGED
package/dist/dev.d.mts
CHANGED
|
@@ -8,7 +8,7 @@ declare const SettingsSchema: z.ZodObject<{
|
|
|
8
8
|
auto_config: z.ZodOptional<z.ZodBoolean>;
|
|
9
9
|
limited_data_use: z.ZodOptional<z.ZodBoolean>;
|
|
10
10
|
identify: z.ZodOptional<z.ZodUnknown>;
|
|
11
|
-
}, z.core.$
|
|
11
|
+
}, z.core.$loose>;
|
|
12
12
|
type Settings$1 = z.infer<typeof SettingsSchema>;
|
|
13
13
|
|
|
14
14
|
declare const MappingSchema: z.ZodObject<{
|
|
@@ -111,12 +111,20 @@ interface Env extends DestinationWeb.Env {
|
|
|
111
111
|
window: {
|
|
112
112
|
ttq: TTQ;
|
|
113
113
|
};
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The queue `setup()` installs until the Pixel script replaces it: each
|
|
117
|
+
* call is kept in `_i.all`.
|
|
118
|
+
*/
|
|
119
|
+
type TTQStub = ((...args: unknown[]) => void) & {
|
|
120
|
+
methods: string[];
|
|
121
|
+
_i: Record<string, unknown[]>;
|
|
122
|
+
loaded: boolean;
|
|
123
|
+
};
|
|
124
|
+
declare global {
|
|
125
|
+
interface Window {
|
|
126
|
+
ttq?: TTQ | TTQStub;
|
|
127
|
+
}
|
|
120
128
|
}
|
|
121
129
|
|
|
122
130
|
/**
|
|
@@ -242,6 +250,14 @@ declare const consentGrantEnableCookie: TikTokStepExample;
|
|
|
242
250
|
* reading its first-party cookie (_ttp) for attribution.
|
|
243
251
|
*/
|
|
244
252
|
declare const consentRevokeDisableCookie: TikTokStepExample;
|
|
253
|
+
/** A silent rule sends no track call. */
|
|
254
|
+
declare const silentRule: TikTokStepExample;
|
|
255
|
+
/**
|
|
256
|
+
* A silent rule that only sets an identity, on an event with no email, phone
|
|
257
|
+
* or id: nothing resolves and the rule suppresses the track, so nothing is
|
|
258
|
+
* sent. A declared skip: an unmet mapping, not a failure.
|
|
259
|
+
*/
|
|
260
|
+
declare const silentIdentifyWithoutData: TikTokStepExample;
|
|
245
261
|
|
|
246
262
|
type step_TikTokStepExample = TikTokStepExample;
|
|
247
263
|
declare const step_consentGrantEnableCookie: typeof consentGrantEnableCookie;
|
|
@@ -253,10 +269,12 @@ declare const step_orderCompleteCompletePayment: typeof orderCompleteCompletePay
|
|
|
253
269
|
declare const step_productViewContent: typeof productViewContent;
|
|
254
270
|
declare const step_ruleIncludeReplaces: typeof ruleIncludeReplaces;
|
|
255
271
|
declare const step_searchSubmitSearch: typeof searchSubmitSearch;
|
|
272
|
+
declare const step_silentIdentifyWithoutData: typeof silentIdentifyWithoutData;
|
|
273
|
+
declare const step_silentRule: typeof silentRule;
|
|
256
274
|
declare const step_userRegisterCompleteRegistration: typeof userRegisterCompleteRegistration;
|
|
257
275
|
declare const step_wildcardIgnored: typeof wildcardIgnored;
|
|
258
276
|
declare namespace step {
|
|
259
|
-
export { type step_TikTokStepExample as TikTokStepExample, step_consentGrantEnableCookie as consentGrantEnableCookie, step_consentRevokeDisableCookie as consentRevokeDisableCookie, step_defaultEventForwarding as defaultEventForwarding, step_destinationLevelIdentify as destinationLevelIdentify, step_destinationLevelInclude as destinationLevelInclude, step_orderCompleteCompletePayment as orderCompleteCompletePayment, step_productViewContent as productViewContent, step_ruleIncludeReplaces as ruleIncludeReplaces, step_searchSubmitSearch as searchSubmitSearch, step_userRegisterCompleteRegistration as userRegisterCompleteRegistration, step_wildcardIgnored as wildcardIgnored };
|
|
277
|
+
export { type step_TikTokStepExample as TikTokStepExample, step_consentGrantEnableCookie as consentGrantEnableCookie, step_consentRevokeDisableCookie as consentRevokeDisableCookie, step_defaultEventForwarding as defaultEventForwarding, step_destinationLevelIdentify as destinationLevelIdentify, step_destinationLevelInclude as destinationLevelInclude, step_orderCompleteCompletePayment as orderCompleteCompletePayment, step_productViewContent as productViewContent, step_ruleIncludeReplaces as ruleIncludeReplaces, step_searchSubmitSearch as searchSubmitSearch, step_silentIdentifyWithoutData as silentIdentifyWithoutData, step_silentRule as silentRule, step_userRegisterCompleteRegistration as userRegisterCompleteRegistration, step_wildcardIgnored as wildcardIgnored };
|
|
260
278
|
}
|
|
261
279
|
|
|
262
280
|
declare const index_env: typeof env;
|
package/dist/dev.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ declare const SettingsSchema: z.ZodObject<{
|
|
|
8
8
|
auto_config: z.ZodOptional<z.ZodBoolean>;
|
|
9
9
|
limited_data_use: z.ZodOptional<z.ZodBoolean>;
|
|
10
10
|
identify: z.ZodOptional<z.ZodUnknown>;
|
|
11
|
-
}, z.core.$
|
|
11
|
+
}, z.core.$loose>;
|
|
12
12
|
type Settings$1 = z.infer<typeof SettingsSchema>;
|
|
13
13
|
|
|
14
14
|
declare const MappingSchema: z.ZodObject<{
|
|
@@ -111,12 +111,20 @@ interface Env extends DestinationWeb.Env {
|
|
|
111
111
|
window: {
|
|
112
112
|
ttq: TTQ;
|
|
113
113
|
};
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The queue `setup()` installs until the Pixel script replaces it: each
|
|
117
|
+
* call is kept in `_i.all`.
|
|
118
|
+
*/
|
|
119
|
+
type TTQStub = ((...args: unknown[]) => void) & {
|
|
120
|
+
methods: string[];
|
|
121
|
+
_i: Record<string, unknown[]>;
|
|
122
|
+
loaded: boolean;
|
|
123
|
+
};
|
|
124
|
+
declare global {
|
|
125
|
+
interface Window {
|
|
126
|
+
ttq?: TTQ | TTQStub;
|
|
127
|
+
}
|
|
120
128
|
}
|
|
121
129
|
|
|
122
130
|
/**
|
|
@@ -242,6 +250,14 @@ declare const consentGrantEnableCookie: TikTokStepExample;
|
|
|
242
250
|
* reading its first-party cookie (_ttp) for attribution.
|
|
243
251
|
*/
|
|
244
252
|
declare const consentRevokeDisableCookie: TikTokStepExample;
|
|
253
|
+
/** A silent rule sends no track call. */
|
|
254
|
+
declare const silentRule: TikTokStepExample;
|
|
255
|
+
/**
|
|
256
|
+
* A silent rule that only sets an identity, on an event with no email, phone
|
|
257
|
+
* or id: nothing resolves and the rule suppresses the track, so nothing is
|
|
258
|
+
* sent. A declared skip: an unmet mapping, not a failure.
|
|
259
|
+
*/
|
|
260
|
+
declare const silentIdentifyWithoutData: TikTokStepExample;
|
|
245
261
|
|
|
246
262
|
type step_TikTokStepExample = TikTokStepExample;
|
|
247
263
|
declare const step_consentGrantEnableCookie: typeof consentGrantEnableCookie;
|
|
@@ -253,10 +269,12 @@ declare const step_orderCompleteCompletePayment: typeof orderCompleteCompletePay
|
|
|
253
269
|
declare const step_productViewContent: typeof productViewContent;
|
|
254
270
|
declare const step_ruleIncludeReplaces: typeof ruleIncludeReplaces;
|
|
255
271
|
declare const step_searchSubmitSearch: typeof searchSubmitSearch;
|
|
272
|
+
declare const step_silentIdentifyWithoutData: typeof silentIdentifyWithoutData;
|
|
273
|
+
declare const step_silentRule: typeof silentRule;
|
|
256
274
|
declare const step_userRegisterCompleteRegistration: typeof userRegisterCompleteRegistration;
|
|
257
275
|
declare const step_wildcardIgnored: typeof wildcardIgnored;
|
|
258
276
|
declare namespace step {
|
|
259
|
-
export { type step_TikTokStepExample as TikTokStepExample, step_consentGrantEnableCookie as consentGrantEnableCookie, step_consentRevokeDisableCookie as consentRevokeDisableCookie, step_defaultEventForwarding as defaultEventForwarding, step_destinationLevelIdentify as destinationLevelIdentify, step_destinationLevelInclude as destinationLevelInclude, step_orderCompleteCompletePayment as orderCompleteCompletePayment, step_productViewContent as productViewContent, step_ruleIncludeReplaces as ruleIncludeReplaces, step_searchSubmitSearch as searchSubmitSearch, step_userRegisterCompleteRegistration as userRegisterCompleteRegistration, step_wildcardIgnored as wildcardIgnored };
|
|
277
|
+
export { type step_TikTokStepExample as TikTokStepExample, step_consentGrantEnableCookie as consentGrantEnableCookie, step_consentRevokeDisableCookie as consentRevokeDisableCookie, step_defaultEventForwarding as defaultEventForwarding, step_destinationLevelIdentify as destinationLevelIdentify, step_destinationLevelInclude as destinationLevelInclude, step_orderCompleteCompletePayment as orderCompleteCompletePayment, step_productViewContent as productViewContent, step_ruleIncludeReplaces as ruleIncludeReplaces, step_searchSubmitSearch as searchSubmitSearch, step_silentIdentifyWithoutData as silentIdentifyWithoutData, step_silentRule as silentRule, step_userRegisterCompleteRegistration as userRegisterCompleteRegistration, step_wildcardIgnored as wildcardIgnored };
|
|
260
278
|
}
|
|
261
279
|
|
|
262
280
|
declare const index_env: typeof env;
|
package/dist/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,o=(e,a)=>{for(var n in a)t(e,n,{get:a[n],enumerable:!0})},r={};o(r,{examples:()=>
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,o=(e,a)=>{for(var n in a)t(e,n,{get:a[n],enumerable:!0})},r={};o(r,{examples:()=>k,schemas:()=>d}),module.exports=(e=r,((e,o,r,d)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let c of n(o))i.call(e,c)||c===r||t(e,c,{get:()=>o[c],enumerable:!(d=a(o,c))||d.enumerable});return e})(t({},"__esModule",{value:!0}),e));var d={};o(d,{MappingSchema:()=>u,SettingsSchema:()=>s,mapping:()=>v,settings:()=>m});var c=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),s=l.z.object({apiKey:l.z.string().min(1).describe('Your TikTok Pixel ID. Find it in TikTok Ads Manager under "Assets" → "Events" → "Web Events" → select your pixel → "Setup Web Event" → "Pixel ID".'),auto_config:l.z.boolean().describe("TikTok default: true. Enable automatic form field detection for Advanced Matching.").optional(),limited_data_use:l.z.boolean().describe("TikTok default: false. Restrict data use for compliance with U.S. state privacy laws.").optional(),identify:l.z.unknown().describe("walkerOS mapping value resolving to an Advanced Matching object with any of: email, phone_number, external_id. All values are auto-hashed (SHA256) by the TikTok SDK before sending.").optional()}).loose(),p=require("@walkeros/core/dev"),u=p.z.object({identify:p.z.unknown().describe("Per-event Advanced Matching mapping. Resolves to an object with any of: email, phone_number, external_id. Overrides destination-level settings.identify for this rule.").optional()}),m=(0,c.zodToSchema)(s),v=(0,c.zodToSchema)(u),k={};o(k,{env:()=>g,step:()=>q});var g={};o(g,{init:()=>h,push:()=>w,simulation:()=>_});var b=require("@walkeros/web-core/dev"),f=()=>{};function y(){return{window:{ttq:Object.assign(()=>{},{load:f,page:f,track:f,identify:f,enableCookie:f,disableCookie:f,methods:["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie"],_i:{},loaded:!0})},document:(0,b.mockScriptDocument)()}}var h=y(),w=y(),_=["call:window.ttq.load","call:window.ttq.track","call:window.ttq.identify","call:window.ttq.page","call:window.ttq.enableCookie","call:window.ttq.disableCookie"],q={};o(q,{consentGrantEnableCookie:()=>D,consentRevokeDisableCookie:()=>I,defaultEventForwarding:()=>T,destinationLevelIdentify:()=>x,destinationLevelInclude:()=>R,orderCompleteCompletePayment:()=>j,productViewContent:()=>S,ruleIncludeReplaces:()=>A,searchSubmitSearch:()=>z,silentIdentifyWithoutData:()=>M,silentRule:()=>O,userRegisterCompleteRegistration:()=>P,wildcardIgnored:()=>E});var C=require("@walkeros/core"),T={title:"Default track",description:"Without a mapping the walker event name is forwarded to ttq.track with an event_id for TikTok dedup.",in:(0,C.getEvent)("product view",{id:"0123456789abcdef"}),out:[["ttq.track","product view",{},{event_id:"0123456789abcdef"}]]},E={public:!1,in:(0,C.getEvent)("product view"),mapping:{ignore:!0},out:[]},S={title:"View content",description:"A product view is renamed to the TikTok ViewContent standard event with content_type, id, value, and currency.",in:(0,C.getEvent)("product view",{id:"11111111aaaaaaaa"}),mapping:{name:"ViewContent",data:{map:{content_type:{value:"product"},content_id:"data.id",content_name:"data.name",content_category:"data.category",value:"data.price",currency:{key:"globals.currency",value:"EUR"}}},include:[]},out:[["ttq.track","ViewContent",{content_type:"product",content_id:"ers",content_name:"Everyday Ruck Snack",value:420,currency:"EUR"},{event_id:"11111111aaaaaaaa"}]]},R={title:"Include data",description:"Destination-level include flattens the event data section into prefixed TikTok event parameters.",in:(0,C.getEvent)("product view",{id:"22222222bbbbbbbb"}),configInclude:["data"],out:[["ttq.track","product view",{data_id:"ers",data_name:"Everyday Ruck Snack",data_color:"black",data_size:"l",data_price:420},{event_id:"22222222bbbbbbbb"}]]},A={title:"Rule include overrides",description:"A per-rule include replaces the destination-level include so this event forwards only globals.",in:(0,C.getEvent)("order complete",{id:"33333333cccccccc"}),configInclude:["data"],mapping:{include:["globals"]},out:[["ttq.track","order complete",{globals_pagegroup:"shop"},{event_id:"33333333cccccccc"}]]},x={title:"Advanced matching",description:"Destination-level identify calls ttq.identify with email, phone, and external id for TikTok advanced matching.",in:(0,C.getEvent)("page view",{id:"44444444dddddddd",data:{email:"user@acme.com",phone:"+14135552671"}}),settings:{identify:{map:{email:"data.email",phone_number:"data.phone",external_id:"user.id"}}},out:[["ttq.identify",{email:"user@acme.com",phone_number:"+14135552671",external_id:"us3r"}],["ttq.track","page view",{},{event_id:"44444444dddddddd"}]]},P={title:"Complete registration",description:"A user register fires ttq.identify for advanced matching and then tracks CompleteRegistration.",in:(0,C.createEvent)({name:"user register",id:"55555555eeeeeeee",data:{email:"new@acme.com",phone:"+14135551234",user_id:"new-user-123"}}),mapping:{name:"CompleteRegistration",include:[],data:{map:{content_type:{value:"product"}}},settings:{identify:{map:{email:"data.email",phone_number:"data.phone",external_id:"data.user_id"}}}},out:[["ttq.identify",{email:"new@acme.com",phone_number:"+14135551234",external_id:"new-user-123"}],["ttq.track","CompleteRegistration",{content_type:"product"},{event_id:"55555555eeeeeeee"}]]},j={title:"Complete payment",description:"A completed order is mapped to TikTok CompletePayment with value, currency, and nested product contents.",in:(0,C.getEvent)("order complete",{id:"66666666ffffffff"}),mapping:{name:"CompletePayment",data:{map:{content_type:{value:"product"},value:"data.value",currency:{key:"data.currency",value:"EUR"},order_id:"data.id",contents:{loop:["nested",{map:{content_id:"data.id",content_name:"data.name",quantity:{key:"data.quantity",value:1},price:"data.price"}}]}}},include:[]},out:[["ttq.track","CompletePayment",{content_type:"product",value:555,currency:"EUR",order_id:"0rd3r1d",contents:[{content_id:"ers",content_name:"Everyday Ruck Snack",quantity:1,price:420},{content_id:"cc",content_name:"Cool Cap",quantity:1,price:42},{content_name:"Surprise",quantity:1}]},{event_id:"66666666ffffffff"}]]},z={title:"Search",description:"A search submit fires TikTok Search with the query field mapped from event data.",in:(0,C.createEvent)({name:"search submit",id:"777777770000aaaa",data:{term:"hiking backpack"}}),mapping:{name:"Search",data:{map:{query:"data.term"}},include:[]},out:[["ttq.track","Search",{query:"hiking backpack"},{event_id:"777777770000aaaa"}]]},D={title:"Consent granted",description:"A walker consent grant for marketing calls ttq.enableCookie so TikTok can set and read its attribution cookie.",command:"consent",in:{marketing:!0},settings:{},out:[["ttq.enableCookie"]]},I={title:"Consent revoked",description:"A walker consent revoke for marketing calls ttq.disableCookie so TikTok stops using its first-party cookie.",command:"consent",before:{marketing:!0},in:{marketing:!1},settings:{},out:[["window.ttq.disableCookie"]]},O={public:!1,description:"A rule with silent: true sends no ttq.track call.",in:(0,C.getEvent)("page view",{timestamp:1700000600}),mapping:{silent:!0},out:[]},M={public:!1,description:"A silent rule whose identify mapping finds no email, phone or id sends nothing: an unmet mapping, not a failure, so the push returns normally.",in:{name:"user update",entity:"user",action:"update"},mapping:{silent:!0,settings:{identify:{map:{email:"data.email",phone_number:"data.phone",external_id:"data.id"}}}},out:[]};//# 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 'Your TikTok Pixel ID. Find it in TikTok Ads Manager under \"Assets\" → \"Events\" → \"Web Events\" → select your pixel → \"Setup Web Event\" → \"Pixel ID\".',\n ),\n // `pageview` removed 2026-04-09 — TikTok's SDK fires auto page view and\n // the knob was unreliable. Let it fire; don't expose a toggle.\n auto_config: z\n .boolean()\n .describe(\n 'TikTok default: true. Enable automatic form field detection for Advanced Matching.',\n )\n .optional(),\n limited_data_use: z\n .boolean()\n .describe(\n 'TikTok default: false. Restrict data use for compliance with U.S. state privacy laws.',\n )\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to an Advanced Matching object with any of: email, phone_number, external_id. All values are auto-hashed (SHA256) by the TikTok SDK before sending.',\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 Advanced Matching mapping. Resolves to an object with any of: email, phone_number, external_id. Overrides destination-level settings.identify for this rule.',\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, TTQ } from '../types';\n\nconst noop = () => {};\n\n/** Build a fresh mock ttq — each call returns a new object so tests can mutate independently. */\nfunction makeMockTTQ(): TTQ {\n const fn = (() => {}) as unknown as TTQ;\n fn.load = noop;\n fn.page = noop;\n fn.track = noop;\n fn.identify = noop;\n fn.enableCookie = noop;\n fn.disableCookie = noop;\n fn.methods = [\n 'page',\n 'track',\n 'identify',\n 'instances',\n 'debug',\n 'on',\n 'off',\n 'once',\n 'ready',\n 'alias',\n 'group',\n 'enableCookie',\n 'disableCookie',\n ];\n fn._i = {};\n fn.loaded = true;\n return fn;\n}\n\n/**\n * Minimal web env — window has a mock ttq. document has the bare minimum\n * for addScript() (createElement + head.appendChild), with no-op\n * implementations so init() can run without a real DOM.\n */\nfunction makeEnv(): Env {\n return {\n window: {\n ttq: makeMockTTQ(),\n },\n document: {\n createElement: () =>\n ({\n src: '',\n async: false,\n }) as unknown as Element,\n head: { appendChild: noop },\n },\n };\n}\n\n/**\n * Pre-init env — destination init() call will set up ttq and load the\n * script. Tests receive this as a starting point.\n */\nexport const init: Env = makeEnv();\n\n/**\n * Post-init env — same shape; the test runner clones this and replaces\n * individual ttq methods with jest.fn() so it can assert on calls.\n */\nexport const push: Env = makeEnv();\n\n/** Simulation tracking paths for CLI --simulate. */\nexport const simulation = [\n 'call:window.ttq.load',\n 'call:window.ttq.track',\n 'call:window.ttq.identify',\n 'call:window.ttq.page',\n 'call:window.ttq.enableCookie',\n 'call:window.ttq.disableCookie',\n];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Examples may optionally carry destination-level settings. The test\n * runner reads `settings` from the example and merges it into the base\n * destination settings on top of the fixed apiKey.\n */\nexport type TikTokStepExample = 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 a ttq.track()\n * call. With no mapping and no destination-level include, the params\n * object is empty. event_id is always passed as the 3rd argument (TikTok\n * dedup between pixel and Events API).\n *\n * NOTE: The raw walkerOS event name \"product view\" (with space) is NOT a\n * TikTok standard event. Without a mapping.name override, TikTok treats\n * it as a custom event - functional for audience building, no\n * optimization. The next example shows the recommended override.\n */\nexport const defaultEventForwarding: TikTokStepExample = {\n title: 'Default track',\n description:\n 'Without a mapping the walker event name is forwarded to ttq.track with an event_id for TikTok dedup.',\n in: getEvent('product view', { id: '0123456789abcdef' }),\n out: [['ttq.track', 'product view', {}, { event_id: '0123456789abcdef' }]],\n};\n\n/**\n * Wildcard ignore - walkerOS's standard way to drop events. The rule\n * matches but does nothing. The destination fires zero SDK calls.\n */\nexport const wildcardIgnored: TikTokStepExample = {\n public: false,\n in: getEvent('product view'),\n mapping: { ignore: true },\n out: [],\n};\n\n/**\n * The canonical TikTok pattern: walkerOS \"product view\" → TikTok\n * \"ViewContent\" via mapping.name. mapping.data builds the TikTok-native\n * parameter shape (content_type, content_id, content_name, value,\n * currency). include is explicitly set to [] so prefixed walkerOS\n * properties don't leak onto the call and confuse TikTok's matcher.\n */\nexport const productViewContent: TikTokStepExample = {\n title: 'View content',\n description:\n 'A product view is renamed to the TikTok ViewContent standard event with content_type, id, value, and currency.',\n in: getEvent('product view', { id: '11111111aaaaaaaa' }),\n mapping: {\n name: 'ViewContent',\n data: {\n map: {\n content_type: { value: 'product' },\n content_id: 'data.id',\n content_name: 'data.name',\n content_category: 'data.category',\n value: 'data.price',\n currency: { key: 'globals.currency', value: 'EUR' },\n },\n },\n include: [],\n },\n out: [\n [\n 'ttq.track',\n 'ViewContent',\n {\n content_type: 'product',\n content_id: 'ers',\n content_name: 'Everyday Ruck Snack',\n // content_category is absent from the default product view fixture;\n // the mapper skips undefined resolutions.\n value: 420,\n currency: 'EUR', // fallback - default fixture has no globals.currency\n },\n { event_id: '11111111aaaaaaaa' },\n ],\n ],\n};\n\n/**\n * Destination-level settings.include flattens the walkerOS `data` section\n * into prefixed TikTok event parameters on every push. This is the\n * \"dump everything\" mode - useful for custom events where TikTok won't\n * do optimization anyway, and no mapping.data is needed.\n */\nexport const destinationLevelInclude: TikTokStepExample = {\n title: 'Include data',\n description:\n 'Destination-level include flattens the event data section into prefixed TikTok event parameters.',\n in: getEvent('product view', { id: '22222222bbbbbbbb' }),\n configInclude: ['data'],\n out: [\n [\n 'ttq.track',\n 'product view',\n {\n data_id: 'ers',\n data_name: 'Everyday Ruck Snack',\n data_color: 'black',\n data_size: 'l',\n data_price: 420,\n },\n { event_id: '22222222bbbbbbbb' },\n ],\n ],\n};\n\n/**\n * Per-rule settings.include REPLACES destination-level include for the\n * matched rule (design doc §6: mapping-level include replaces, not\n * merges with, destination-level include).\n */\nexport const ruleIncludeReplaces: TikTokStepExample = {\n title: 'Rule include overrides',\n description:\n 'A per-rule include replaces the destination-level include so this event forwards only globals.',\n in: getEvent('order complete', { id: '33333333cccccccc' }),\n configInclude: ['data'],\n mapping: {\n include: ['globals'],\n },\n out: [\n [\n 'ttq.track',\n 'order complete',\n {\n globals_pagegroup: 'shop',\n },\n { event_id: '33333333cccccccc' },\n ],\n ],\n};\n\n/**\n * Destination-level settings.identify fires on the first push (once the\n * state cache is empty). Advanced Matching parameters (email,\n * phone_number, external_id) are passed to ttq.identify() which\n * auto-hashes them SHA256 before sending. Subsequent pushes with\n * unchanged values do NOT re-fire ttq.identify() - runtime state tracks\n * the last-resolved identity.\n *\n * walkerOS's default user fixture has user.id='us3r' and no email/phone,\n * so the example injects data and maps from there.\n */\nexport const destinationLevelIdentify: TikTokStepExample = {\n title: 'Advanced matching',\n description:\n 'Destination-level identify calls ttq.identify with email, phone, and external id for TikTok advanced matching.',\n in: getEvent('page view', {\n id: '44444444dddddddd',\n data: {\n email: 'user@acme.com',\n phone: '+14135552671',\n },\n }),\n settings: {\n identify: {\n map: {\n email: 'data.email',\n phone_number: 'data.phone',\n external_id: 'user.id',\n },\n },\n },\n out: [\n [\n 'ttq.identify',\n {\n email: 'user@acme.com',\n phone_number: '+14135552671',\n external_id: 'us3r',\n },\n ],\n ['ttq.track', 'page view', {}, { event_id: '44444444dddddddd' }],\n ],\n};\n\n/**\n * User registration → CompleteRegistration standard event with per-event\n * identify. The user just provided their email + phone, so this is the\n * moment to fire Advanced Matching for this session. The per-event\n * identify overrides any destination-level identify for this one push.\n */\nexport const userRegisterCompleteRegistration: TikTokStepExample = {\n title: 'Complete registration',\n description:\n 'A user register fires ttq.identify for advanced matching and then tracks CompleteRegistration.',\n in: getEvent('user register', {\n id: '55555555eeeeeeee',\n data: {\n email: 'new@acme.com',\n phone: '+14135551234',\n user_id: 'new-user-123',\n },\n }),\n mapping: {\n name: 'CompleteRegistration',\n include: [],\n data: {\n map: {\n content_type: { value: 'product' },\n },\n },\n settings: {\n identify: {\n map: {\n email: 'data.email',\n phone_number: 'data.phone',\n external_id: 'data.user_id',\n },\n },\n },\n },\n out: [\n [\n 'ttq.identify',\n {\n email: 'new@acme.com',\n phone_number: '+14135551234',\n external_id: 'new-user-123',\n },\n ],\n [\n 'ttq.track',\n 'CompleteRegistration',\n {\n content_type: 'product',\n },\n { event_id: '55555555eeeeeeee' },\n ],\n ],\n};\n\n/**\n * Multi-product order → CompletePayment standard event. The canonical\n * TikTok ecommerce pattern:\n * - mapping.name flips the walkerOS event to TikTok's rigid taxonomy\n * - mapping.data builds the TikTok-native parameter shape\n * - loop iterates event.nested to produce the `contents` array, one\n * entry per product\n * - { key, value: 'EUR' } provides a currency fallback if data.currency\n * is absent (here data.currency is 'EUR' so the key wins)\n *\n * The default \"order complete\" fixture has 3 nested entries: two\n * products (ers, cc) and one gift (Surprise - no id, no price).\n */\nexport const orderCompleteCompletePayment: TikTokStepExample = {\n title: 'Complete payment',\n description:\n 'A completed order is mapped to TikTok CompletePayment with value, currency, and nested product contents.',\n in: getEvent('order complete', { id: '66666666ffffffff' }),\n mapping: {\n name: 'CompletePayment',\n data: {\n map: {\n content_type: { value: 'product' },\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n order_id: 'data.id',\n contents: {\n loop: [\n 'nested',\n {\n map: {\n content_id: 'data.id',\n content_name: 'data.name',\n quantity: { key: 'data.quantity', value: 1 },\n price: 'data.price',\n },\n },\n ],\n },\n },\n },\n include: [],\n },\n out: [\n [\n 'ttq.track',\n 'CompletePayment',\n {\n content_type: 'product',\n value: 555,\n currency: 'EUR',\n order_id: '0rd3r1d',\n contents: [\n {\n content_id: 'ers',\n content_name: 'Everyday Ruck Snack',\n quantity: 1, // fallback - fixture has no data.quantity\n price: 420,\n },\n {\n content_id: 'cc',\n content_name: 'Cool Cap',\n quantity: 1,\n price: 42,\n },\n {\n // gift entry - { name: 'Surprise' }, no id and no price.\n // walkerOS map skips keys whose resolved value is undefined.\n content_name: 'Surprise',\n quantity: 1,\n },\n ],\n },\n { event_id: '66666666ffffffff' },\n ],\n ],\n};\n\n/**\n * Search → TikTok Search standard event. Minimal example that shows how\n * a walkerOS search event flips through mapping.name with a single\n * mapping.data field (the query string).\n */\nexport const searchSubmitSearch: TikTokStepExample = {\n title: 'Search',\n description:\n 'A search submit fires TikTok Search with the query field mapped from event data.',\n in: getEvent('search submit', {\n id: '777777770000aaaa',\n data: {\n term: 'hiking backpack',\n },\n }),\n mapping: {\n name: 'Search',\n data: {\n map: {\n query: 'data.term',\n },\n },\n include: [],\n },\n out: [\n [\n 'ttq.track',\n 'Search',\n {\n query: 'hiking backpack',\n },\n { event_id: '777777770000aaaa' },\n ],\n ],\n};\n\n/**\n * Consent granted → ttq.enableCookie(). The destination checks the\n * consent keys declared in config.consent (here \"marketing\" - TikTok is\n * an ad platform, not analytics) and toggles cookie behavior.\n *\n * Uses the canonical StepExample.command='consent' pattern: the test\n * runner dispatches via elb('walker consent', in) instead of pushing\n * an event.\n */\nexport const consentGrantEnableCookie: TikTokStepExample = {\n title: 'Consent granted',\n description:\n 'A walker consent grant for marketing calls ttq.enableCookie so TikTok can set and read its attribution cookie.',\n command: 'consent',\n in: { marketing: true } as WalkerOS.Consent,\n settings: {} as Partial<Settings>, // consent key is derived from config.consent\n out: [['ttq.enableCookie']],\n};\n\n/**\n * Consent revoked → ttq.disableCookie(). TikTok stops setting and\n * reading its first-party cookie (_ttp) for attribution.\n */\nexport const consentRevokeDisableCookie: TikTokStepExample = {\n title: 'Consent revoked',\n description:\n 'A walker consent revoke for marketing calls ttq.disableCookie so TikTok stops using its first-party cookie.',\n command: 'consent',\n before: { marketing: true },\n in: { marketing: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['ttq.enableCookie'], ['ttq.disableCookie']],\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\n .object({\n apiKey: z\n .string()\n .min(1)\n .describe(\n 'Your TikTok Pixel ID. Find it in TikTok Ads Manager under \"Assets\" → \"Events\" → \"Web Events\" → select your pixel → \"Setup Web Event\" → \"Pixel ID\".',\n ),\n // `pageview` removed 2026-04-09 — TikTok's SDK fires auto page view and\n // the knob was unreliable. Let it fire; don't expose a toggle.\n auto_config: z\n .boolean()\n .describe(\n 'TikTok default: true. Enable automatic form field detection for Advanced Matching.',\n )\n .optional(),\n limited_data_use: z\n .boolean()\n .describe(\n 'TikTok default: false. Restrict data use for compliance with U.S. state privacy laws.',\n )\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to an Advanced Matching object with any of: email, phone_number, external_id. All values are auto-hashed (SHA256) by the TikTok SDK before sending.',\n )\n .optional(),\n })\n // Pass-through settings are loose: every other TikTok option is forwarded\n // to ttq.load() as given.\n .loose();\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 Advanced Matching mapping. Resolves to an object with any of: email, phone_number, external_id. Overrides destination-level settings.identify for this rule.',\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 { mockScriptDocument } from '@walkeros/web-core/dev';\nimport type { Env, TTQ } from '../types';\n\nconst noop = () => {};\n\n/** Build a fresh mock ttq: each call returns a new object so tests can mutate independently. */\nfunction makeMockTTQ(): TTQ {\n return Object.assign(() => {}, {\n load: noop,\n page: noop,\n track: noop,\n identify: noop,\n enableCookie: noop,\n disableCookie: noop,\n methods: [\n 'page',\n 'track',\n 'identify',\n 'instances',\n 'debug',\n 'on',\n 'off',\n 'once',\n 'ready',\n 'alias',\n 'group',\n 'enableCookie',\n 'disableCookie',\n ],\n _i: {},\n loaded: true,\n });\n}\n\n/** Minimal web env: window has a mock ttq, document takes the Pixel script. */\nfunction makeEnv(): Env {\n return {\n window: {\n ttq: makeMockTTQ(),\n },\n document: mockScriptDocument(),\n };\n}\n\n/**\n * Pre-init env — destination init() call will set up ttq and load the\n * script. Tests receive this as a starting point.\n */\nexport const init: Env = makeEnv();\n\n/**\n * Post-init env — same shape; the test runner clones this and replaces\n * individual ttq methods with jest.fn() so it can assert on calls.\n */\nexport const push: Env = makeEnv();\n\n/** Simulation tracking paths for CLI --simulate. */\nexport const simulation = [\n 'call:window.ttq.load',\n 'call:window.ttq.track',\n 'call:window.ttq.identify',\n 'call:window.ttq.page',\n 'call:window.ttq.enableCookie',\n 'call:window.ttq.disableCookie',\n];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { createEvent, getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Examples may optionally carry destination-level settings. The test\n * runner reads `settings` from the example and merges it into the base\n * destination settings on top of the fixed apiKey.\n */\nexport type TikTokStepExample = 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 a ttq.track()\n * call. With no mapping and no destination-level include, the params\n * object is empty. event_id is always passed as the 3rd argument (TikTok\n * dedup between pixel and Events API).\n *\n * NOTE: The raw walkerOS event name \"product view\" (with space) is NOT a\n * TikTok standard event. Without a mapping.name override, TikTok treats\n * it as a custom event - functional for audience building, no\n * optimization. The next example shows the recommended override.\n */\nexport const defaultEventForwarding: TikTokStepExample = {\n title: 'Default track',\n description:\n 'Without a mapping the walker event name is forwarded to ttq.track with an event_id for TikTok dedup.',\n in: getEvent('product view', { id: '0123456789abcdef' }),\n out: [['ttq.track', 'product view', {}, { event_id: '0123456789abcdef' }]],\n};\n\n/**\n * Wildcard ignore - walkerOS's standard way to drop events. The rule\n * matches but does nothing. The destination fires zero SDK calls.\n */\nexport const wildcardIgnored: TikTokStepExample = {\n public: false,\n in: getEvent('product view'),\n mapping: { ignore: true },\n out: [],\n};\n\n/**\n * The canonical TikTok pattern: walkerOS \"product view\" → TikTok\n * \"ViewContent\" via mapping.name. mapping.data builds the TikTok-native\n * parameter shape (content_type, content_id, content_name, value,\n * currency). include is explicitly set to [] so prefixed walkerOS\n * properties don't leak onto the call and confuse TikTok's matcher.\n */\nexport const productViewContent: TikTokStepExample = {\n title: 'View content',\n description:\n 'A product view is renamed to the TikTok ViewContent standard event with content_type, id, value, and currency.',\n in: getEvent('product view', { id: '11111111aaaaaaaa' }),\n mapping: {\n name: 'ViewContent',\n data: {\n map: {\n content_type: { value: 'product' },\n content_id: 'data.id',\n content_name: 'data.name',\n content_category: 'data.category',\n value: 'data.price',\n currency: { key: 'globals.currency', value: 'EUR' },\n },\n },\n include: [],\n },\n out: [\n [\n 'ttq.track',\n 'ViewContent',\n {\n content_type: 'product',\n content_id: 'ers',\n content_name: 'Everyday Ruck Snack',\n // content_category is absent from the default product view fixture;\n // the mapper skips undefined resolutions.\n value: 420,\n currency: 'EUR', // fallback - default fixture has no globals.currency\n },\n { event_id: '11111111aaaaaaaa' },\n ],\n ],\n};\n\n/**\n * Destination-level settings.include flattens the walkerOS `data` section\n * into prefixed TikTok event parameters on every push. This is the\n * \"dump everything\" mode - useful for custom events where TikTok won't\n * do optimization anyway, and no mapping.data is needed.\n */\nexport const destinationLevelInclude: TikTokStepExample = {\n title: 'Include data',\n description:\n 'Destination-level include flattens the event data section into prefixed TikTok event parameters.',\n in: getEvent('product view', { id: '22222222bbbbbbbb' }),\n configInclude: ['data'],\n out: [\n [\n 'ttq.track',\n 'product view',\n {\n data_id: 'ers',\n data_name: 'Everyday Ruck Snack',\n data_color: 'black',\n data_size: 'l',\n data_price: 420,\n },\n { event_id: '22222222bbbbbbbb' },\n ],\n ],\n};\n\n/**\n * Per-rule settings.include REPLACES destination-level include for the\n * matched rule (design doc §6: mapping-level include replaces, not\n * merges with, destination-level include).\n */\nexport const ruleIncludeReplaces: TikTokStepExample = {\n title: 'Rule include overrides',\n description:\n 'A per-rule include replaces the destination-level include so this event forwards only globals.',\n in: getEvent('order complete', { id: '33333333cccccccc' }),\n configInclude: ['data'],\n mapping: {\n include: ['globals'],\n },\n out: [\n [\n 'ttq.track',\n 'order complete',\n {\n globals_pagegroup: 'shop',\n },\n { event_id: '33333333cccccccc' },\n ],\n ],\n};\n\n/**\n * Destination-level settings.identify fires on the first push (once the\n * state cache is empty). Advanced Matching parameters (email,\n * phone_number, external_id) are passed to ttq.identify() which\n * auto-hashes them SHA256 before sending. Subsequent pushes with\n * unchanged values do NOT re-fire ttq.identify() - runtime state tracks\n * the last-resolved identity.\n *\n * walkerOS's default user fixture has user.id='us3r' and no email/phone,\n * so the example injects data and maps from there.\n */\nexport const destinationLevelIdentify: TikTokStepExample = {\n title: 'Advanced matching',\n description:\n 'Destination-level identify calls ttq.identify with email, phone, and external id for TikTok advanced matching.',\n in: getEvent('page view', {\n id: '44444444dddddddd',\n data: {\n email: 'user@acme.com',\n phone: '+14135552671',\n },\n }),\n settings: {\n identify: {\n map: {\n email: 'data.email',\n phone_number: 'data.phone',\n external_id: 'user.id',\n },\n },\n },\n out: [\n [\n 'ttq.identify',\n {\n email: 'user@acme.com',\n phone_number: '+14135552671',\n external_id: 'us3r',\n },\n ],\n ['ttq.track', 'page view', {}, { event_id: '44444444dddddddd' }],\n ],\n};\n\n/**\n * User registration → CompleteRegistration standard event with per-event\n * identify. The user just provided their email + phone, so this is the\n * moment to fire Advanced Matching for this session. The per-event\n * identify overrides any destination-level identify for this one push.\n */\nexport const userRegisterCompleteRegistration: TikTokStepExample = {\n title: 'Complete registration',\n description:\n 'A user register fires ttq.identify for advanced matching and then tracks CompleteRegistration.',\n in: createEvent({\n name: 'user register',\n id: '55555555eeeeeeee',\n data: {\n email: 'new@acme.com',\n phone: '+14135551234',\n user_id: 'new-user-123',\n },\n }),\n mapping: {\n name: 'CompleteRegistration',\n include: [],\n data: {\n map: {\n content_type: { value: 'product' },\n },\n },\n settings: {\n identify: {\n map: {\n email: 'data.email',\n phone_number: 'data.phone',\n external_id: 'data.user_id',\n },\n },\n },\n },\n out: [\n [\n 'ttq.identify',\n {\n email: 'new@acme.com',\n phone_number: '+14135551234',\n external_id: 'new-user-123',\n },\n ],\n [\n 'ttq.track',\n 'CompleteRegistration',\n {\n content_type: 'product',\n },\n { event_id: '55555555eeeeeeee' },\n ],\n ],\n};\n\n/**\n * Multi-product order → CompletePayment standard event. The canonical\n * TikTok ecommerce pattern:\n * - mapping.name flips the walkerOS event to TikTok's rigid taxonomy\n * - mapping.data builds the TikTok-native parameter shape\n * - loop iterates event.nested to produce the `contents` array, one\n * entry per product\n * - { key, value: 'EUR' } provides a currency fallback if data.currency\n * is absent (here data.currency is 'EUR' so the key wins)\n *\n * The default \"order complete\" fixture has 3 nested entries: two\n * products (ers, cc) and one gift (Surprise - no id, no price).\n */\nexport const orderCompleteCompletePayment: TikTokStepExample = {\n title: 'Complete payment',\n description:\n 'A completed order is mapped to TikTok CompletePayment with value, currency, and nested product contents.',\n in: getEvent('order complete', { id: '66666666ffffffff' }),\n mapping: {\n name: 'CompletePayment',\n data: {\n map: {\n content_type: { value: 'product' },\n value: 'data.value',\n currency: { key: 'data.currency', value: 'EUR' },\n order_id: 'data.id',\n contents: {\n loop: [\n 'nested',\n {\n map: {\n content_id: 'data.id',\n content_name: 'data.name',\n quantity: { key: 'data.quantity', value: 1 },\n price: 'data.price',\n },\n },\n ],\n },\n },\n },\n include: [],\n },\n out: [\n [\n 'ttq.track',\n 'CompletePayment',\n {\n content_type: 'product',\n value: 555,\n currency: 'EUR',\n order_id: '0rd3r1d',\n contents: [\n {\n content_id: 'ers',\n content_name: 'Everyday Ruck Snack',\n quantity: 1, // fallback - fixture has no data.quantity\n price: 420,\n },\n {\n content_id: 'cc',\n content_name: 'Cool Cap',\n quantity: 1,\n price: 42,\n },\n {\n // gift entry - { name: 'Surprise' }, no id and no price.\n // walkerOS map skips keys whose resolved value is undefined.\n content_name: 'Surprise',\n quantity: 1,\n },\n ],\n },\n { event_id: '66666666ffffffff' },\n ],\n ],\n};\n\n/**\n * Search → TikTok Search standard event. Minimal example that shows how\n * a walkerOS search event flips through mapping.name with a single\n * mapping.data field (the query string).\n */\nexport const searchSubmitSearch: TikTokStepExample = {\n title: 'Search',\n description:\n 'A search submit fires TikTok Search with the query field mapped from event data.',\n in: createEvent({\n name: 'search submit',\n id: '777777770000aaaa',\n data: {\n term: 'hiking backpack',\n },\n }),\n mapping: {\n name: 'Search',\n data: {\n map: {\n query: 'data.term',\n },\n },\n include: [],\n },\n out: [\n [\n 'ttq.track',\n 'Search',\n {\n query: 'hiking backpack',\n },\n { event_id: '777777770000aaaa' },\n ],\n ],\n};\n\n/**\n * Consent granted → ttq.enableCookie(). The destination checks the\n * consent keys declared in config.consent (here \"marketing\" - TikTok is\n * an ad platform, not analytics) and toggles cookie behavior.\n *\n * Uses the canonical StepExample.command='consent' pattern: the test\n * runner dispatches via elb('walker consent', in) instead of pushing\n * an event.\n */\nexport const consentGrantEnableCookie: TikTokStepExample = {\n title: 'Consent granted',\n description:\n 'A walker consent grant for marketing calls ttq.enableCookie so TikTok can set and read its attribution cookie.',\n command: 'consent',\n in: { marketing: true } as WalkerOS.Consent,\n settings: {} as Partial<Settings>, // consent key is derived from config.consent\n out: [['ttq.enableCookie']],\n};\n\n/**\n * Consent revoked → ttq.disableCookie(). TikTok stops setting and\n * reading its first-party cookie (_ttp) for attribution.\n */\nexport const consentRevokeDisableCookie: TikTokStepExample = {\n title: 'Consent revoked',\n description:\n 'A walker consent revoke for marketing calls ttq.disableCookie so TikTok stops using its first-party cookie.',\n command: 'consent',\n before: { marketing: true },\n in: { marketing: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['window.ttq.disableCookie']],\n};\n\n/** A silent rule sends no track call. */\nexport const silentRule: TikTokStepExample = {\n public: false,\n description: 'A rule with silent: true sends no ttq.track call.',\n in: getEvent('page view', { timestamp: 1700000600 }),\n mapping: { silent: true },\n out: [],\n};\n\n/**\n * A silent rule that only sets an identity, on an event with no email, phone\n * or id: nothing resolves and the rule suppresses the track, so nothing is\n * sent. A declared skip: an unmet mapping, not a failure.\n */\nexport const silentIdentifyWithoutData: TikTokStepExample = {\n public: false,\n description:\n 'A silent rule whose identify mapping finds no email, phone or id sends nothing: an unmet mapping, not a failure, so the push returns normally.',\n in: { name: 'user update', entity: 'user', action: 'update' },\n mapping: {\n silent: true,\n settings: {\n identify: {\n map: {\n email: 'data.email',\n phone_number: 'data.phone',\n external_id: 'data.id',\n },\n },\n },\n },\n out: [],\n};\n"],"mappings":"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","names":["import_dev","import_dev","import_dev"]}
|
package/dist/dev.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,t=(t,a)=>{for(var n in a)e(t,n,{get:a[n],enumerable:!0})},a={};t(a,{MappingSchema:()=>r,SettingsSchema:()=>o,mapping:()=>l,settings:()=>c});import{zodToSchema as n}from"@walkeros/core/dev";import{z as i}from"@walkeros/core/dev";var o=i.object({apiKey:i.string().min(1).describe('Your TikTok Pixel ID. Find it in TikTok Ads Manager under "Assets" → "Events" → "Web Events" → select your pixel → "Setup Web Event" → "Pixel ID".'),auto_config:i.boolean().describe("TikTok default: true. Enable automatic form field detection for Advanced Matching.").optional(),limited_data_use:i.boolean().describe("TikTok default: false. Restrict data use for compliance with U.S. state privacy laws.").optional(),identify:i.unknown().describe("walkerOS mapping value resolving to an Advanced Matching object with any of: email, phone_number, external_id. All values are auto-hashed (SHA256) by the TikTok SDK before sending.").optional()});import{z as d}from"@walkeros/core/dev";var r=d.object({identify:d.unknown().describe("Per-event Advanced Matching mapping. Resolves to an object with any of: email, phone_number, external_id. Overrides destination-level settings.identify for this rule.").optional()}),c=n(o),l=n(r),s={};t(s,{env:()=>p,step:()=>
|
|
1
|
+
var e=Object.defineProperty,t=(t,a)=>{for(var n in a)e(t,n,{get:a[n],enumerable:!0})},a={};t(a,{MappingSchema:()=>r,SettingsSchema:()=>o,mapping:()=>l,settings:()=>c});import{zodToSchema as n}from"@walkeros/core/dev";import{z as i}from"@walkeros/core/dev";var o=i.object({apiKey:i.string().min(1).describe('Your TikTok Pixel ID. Find it in TikTok Ads Manager under "Assets" → "Events" → "Web Events" → select your pixel → "Setup Web Event" → "Pixel ID".'),auto_config:i.boolean().describe("TikTok default: true. Enable automatic form field detection for Advanced Matching.").optional(),limited_data_use:i.boolean().describe("TikTok default: false. Restrict data use for compliance with U.S. state privacy laws.").optional(),identify:i.unknown().describe("walkerOS mapping value resolving to an Advanced Matching object with any of: email, phone_number, external_id. All values are auto-hashed (SHA256) by the TikTok SDK before sending.").optional()}).loose();import{z as d}from"@walkeros/core/dev";var r=d.object({identify:d.unknown().describe("Per-event Advanced Matching mapping. Resolves to an object with any of: email, phone_number, external_id. Overrides destination-level settings.identify for this rule.").optional()}),c=n(o),l=n(r),s={};t(s,{env:()=>p,step:()=>b});var p={};t(p,{init:()=>v,push:()=>f,simulation:()=>g});import{mockScriptDocument as u}from"@walkeros/web-core/dev";var m=()=>{};function k(){return{window:{ttq:Object.assign(()=>{},{load:m,page:m,track:m,identify:m,enableCookie:m,disableCookie:m,methods:["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie"],_i:{},loaded:!0})},document:u()}}var v=k(),f=k(),g=["call:window.ttq.load","call:window.ttq.track","call:window.ttq.identify","call:window.ttq.page","call:window.ttq.enableCookie","call:window.ttq.disableCookie"],b={};t(b,{consentGrantEnableCookie:()=>E,consentRevokeDisableCookie:()=>I,defaultEventForwarding:()=>w,destinationLevelIdentify:()=>R,destinationLevelInclude:()=>C,orderCompleteCompletePayment:()=>A,productViewContent:()=>q,ruleIncludeReplaces:()=>T,searchSubmitSearch:()=>x,silentIdentifyWithoutData:()=>P,silentRule:()=>D,userRegisterCompleteRegistration:()=>S,wildcardIgnored:()=>_});import{createEvent as y,getEvent as h}from"@walkeros/core";var w={title:"Default track",description:"Without a mapping the walker event name is forwarded to ttq.track with an event_id for TikTok dedup.",in:h("product view",{id:"0123456789abcdef"}),out:[["ttq.track","product view",{},{event_id:"0123456789abcdef"}]]},_={public:!1,in:h("product view"),mapping:{ignore:!0},out:[]},q={title:"View content",description:"A product view is renamed to the TikTok ViewContent standard event with content_type, id, value, and currency.",in:h("product view",{id:"11111111aaaaaaaa"}),mapping:{name:"ViewContent",data:{map:{content_type:{value:"product"},content_id:"data.id",content_name:"data.name",content_category:"data.category",value:"data.price",currency:{key:"globals.currency",value:"EUR"}}},include:[]},out:[["ttq.track","ViewContent",{content_type:"product",content_id:"ers",content_name:"Everyday Ruck Snack",value:420,currency:"EUR"},{event_id:"11111111aaaaaaaa"}]]},C={title:"Include data",description:"Destination-level include flattens the event data section into prefixed TikTok event parameters.",in:h("product view",{id:"22222222bbbbbbbb"}),configInclude:["data"],out:[["ttq.track","product view",{data_id:"ers",data_name:"Everyday Ruck Snack",data_color:"black",data_size:"l",data_price:420},{event_id:"22222222bbbbbbbb"}]]},T={title:"Rule include overrides",description:"A per-rule include replaces the destination-level include so this event forwards only globals.",in:h("order complete",{id:"33333333cccccccc"}),configInclude:["data"],mapping:{include:["globals"]},out:[["ttq.track","order complete",{globals_pagegroup:"shop"},{event_id:"33333333cccccccc"}]]},R={title:"Advanced matching",description:"Destination-level identify calls ttq.identify with email, phone, and external id for TikTok advanced matching.",in:h("page view",{id:"44444444dddddddd",data:{email:"user@acme.com",phone:"+14135552671"}}),settings:{identify:{map:{email:"data.email",phone_number:"data.phone",external_id:"user.id"}}},out:[["ttq.identify",{email:"user@acme.com",phone_number:"+14135552671",external_id:"us3r"}],["ttq.track","page view",{},{event_id:"44444444dddddddd"}]]},S={title:"Complete registration",description:"A user register fires ttq.identify for advanced matching and then tracks CompleteRegistration.",in:y({name:"user register",id:"55555555eeeeeeee",data:{email:"new@acme.com",phone:"+14135551234",user_id:"new-user-123"}}),mapping:{name:"CompleteRegistration",include:[],data:{map:{content_type:{value:"product"}}},settings:{identify:{map:{email:"data.email",phone_number:"data.phone",external_id:"data.user_id"}}}},out:[["ttq.identify",{email:"new@acme.com",phone_number:"+14135551234",external_id:"new-user-123"}],["ttq.track","CompleteRegistration",{content_type:"product"},{event_id:"55555555eeeeeeee"}]]},A={title:"Complete payment",description:"A completed order is mapped to TikTok CompletePayment with value, currency, and nested product contents.",in:h("order complete",{id:"66666666ffffffff"}),mapping:{name:"CompletePayment",data:{map:{content_type:{value:"product"},value:"data.value",currency:{key:"data.currency",value:"EUR"},order_id:"data.id",contents:{loop:["nested",{map:{content_id:"data.id",content_name:"data.name",quantity:{key:"data.quantity",value:1},price:"data.price"}}]}}},include:[]},out:[["ttq.track","CompletePayment",{content_type:"product",value:555,currency:"EUR",order_id:"0rd3r1d",contents:[{content_id:"ers",content_name:"Everyday Ruck Snack",quantity:1,price:420},{content_id:"cc",content_name:"Cool Cap",quantity:1,price:42},{content_name:"Surprise",quantity:1}]},{event_id:"66666666ffffffff"}]]},x={title:"Search",description:"A search submit fires TikTok Search with the query field mapped from event data.",in:y({name:"search submit",id:"777777770000aaaa",data:{term:"hiking backpack"}}),mapping:{name:"Search",data:{map:{query:"data.term"}},include:[]},out:[["ttq.track","Search",{query:"hiking backpack"},{event_id:"777777770000aaaa"}]]},E={title:"Consent granted",description:"A walker consent grant for marketing calls ttq.enableCookie so TikTok can set and read its attribution cookie.",command:"consent",in:{marketing:!0},settings:{},out:[["ttq.enableCookie"]]},I={title:"Consent revoked",description:"A walker consent revoke for marketing calls ttq.disableCookie so TikTok stops using its first-party cookie.",command:"consent",before:{marketing:!0},in:{marketing:!1},settings:{},out:[["window.ttq.disableCookie"]]},D={public:!1,description:"A rule with silent: true sends no ttq.track call.",in:h("page view",{timestamp:1700000600}),mapping:{silent:!0},out:[]},P={public:!1,description:"A silent rule whose identify mapping finds no email, phone or id sends nothing: an unmet mapping, not a failure, so the push returns normally.",in:{name:"user update",entity:"user",action:"update"},mapping:{silent:!0,settings:{identify:{map:{email:"data.email",phone_number:"data.phone",external_id:"data.id"}}}},out:[]};export{s as examples,a 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 'Your TikTok Pixel ID. Find it in TikTok Ads Manager under \"Assets\" → \"Events\" → \"Web Events\" → select your pixel → \"Setup Web Event\" → \"Pixel ID\".',\n ),\n // `pageview` removed 2026-04-09 — TikTok's SDK fires auto page view and\n // the knob was unreliable. Let it fire; don't expose a toggle.\n auto_config: z\n .boolean()\n .describe(\n 'TikTok default: true. Enable automatic form field detection for Advanced Matching.',\n )\n .optional(),\n limited_data_use: z\n .boolean()\n .describe(\n 'TikTok default: false. Restrict data use for compliance with U.S. state privacy laws.',\n )\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to an Advanced Matching object with any of: email, phone_number, external_id. All values are auto-hashed (SHA256) by the TikTok SDK before sending.',\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 Advanced Matching mapping. Resolves to an object with any of: email, phone_number, external_id. Overrides destination-level settings.identify for this rule.',\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, TTQ } from '../types';\n\nconst noop = () => {};\n\n/** Build a fresh mock ttq — each call returns a new object so tests can mutate independently. */\nfunction makeMockTTQ(): TTQ {\n const fn = (() => {}) as unknown as TTQ;\n fn.load = noop;\n fn.page = noop;\n fn.track = noop;\n fn.identify = noop;\n fn.enableCookie = noop;\n fn.disableCookie = noop;\n fn.methods = [\n 'page',\n 'track',\n 'identify',\n 'instances',\n 'debug',\n 'on',\n 'off',\n 'once',\n 'ready',\n 'alias',\n 'group',\n 'enableCookie',\n 'disableCookie',\n ];\n fn._i = {};\n fn.loaded = true;\n return fn;\n}\n\n/**\n * Minimal web env — window has a mock ttq. document has the bare minimum\n * for addScript() (createElement + head.appendChild), with no-op\n * implementations so init() can run without a real DOM.\n */\nfunction makeEnv(): Env {\n return {\n window: {\n ttq: makeMockTTQ(),\n },\n document: {\n createElement: () =>\n ({\n src: '',\n async: false,\n }) as unknown as Element,\n head: { appendChild: noop },\n },\n };\n}\n\n/**\n * Pre-init env — destination init() call will set up ttq and load the\n * script. Tests receive this as a starting point.\n */\nexport const init: Env = makeEnv();\n\n/**\n * Post-init env — same shape; the test runner clones this and replaces\n * individual ttq methods with jest.fn() so it can assert on calls.\n */\nexport const push: Env = makeEnv();\n\n/** Simulation tracking paths for CLI --simulate. */\nexport const simulation = [\n 'call:window.ttq.load',\n 'call:window.ttq.track',\n 'call:window.ttq.identify',\n 'call:window.ttq.page',\n 'call:window.ttq.enableCookie',\n 'call:window.ttq.disableCookie',\n];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Examples may optionally carry destination-level settings. The test\n * runner reads `settings` from the example and merges it into the base\n * destination settings on top of the fixed apiKey.\n */\nexport type TikTokStepExample = 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 a ttq.track()\n * call. With no mapping and no destination-level include, the params\n * object is empty. event_id is always passed as the 3rd argument (TikTok\n * dedup between pixel and Events API).\n *\n * NOTE: The raw walkerOS event name \"product view\" (with space) is NOT a\n * TikTok standard event. Without a mapping.name override, TikTok treats\n * it as a custom event - functional for audience building, no\n * optimization. The next example shows the recommended override.\n */\nexport const defaultEventForwarding: TikTokStepExample = {\n title: 'Default track',\n description:\n 'Without a mapping the walker event name is forwarded to ttq.track with an event_id for TikTok dedup.',\n in: getEvent('product view', { id: '0123456789abcdef' }),\n out: [['ttq.track', 'product view', {}, { event_id: '0123456789abcdef' }]],\n};\n\n/**\n * Wildcard ignore - walkerOS's standard way to drop events. The rule\n * matches but does nothing. The destination fires zero SDK calls.\n */\nexport const wildcardIgnored: TikTokStepExample = {\n public: false,\n in: getEvent('product view'),\n mapping: { ignore: true },\n out: [],\n};\n\n/**\n * The canonical TikTok pattern: walkerOS \"product view\" → TikTok\n * \"ViewContent\" via mapping.name. mapping.data builds the TikTok-native\n * parameter shape (content_type, content_id, content_name, value,\n * currency). include is explicitly set to [] so prefixed walkerOS\n * properties don't leak onto the call and confuse TikTok's matcher.\n */\nexport const productViewContent: TikTokStepExample = {\n title: 'View content',\n description:\n 'A product view is renamed to the TikTok ViewContent standard event with content_type, id, value, and currency.',\n in: getEvent('product view', { id: '11111111aaaaaaaa' }),\n mapping: {\n name: 'ViewContent',\n data: {\n map: {\n content_type: { value: 'product' },\n content_id: 'data.id',\n content_name: 'data.name',\n content_category: 'data.category',\n value: 'data.price',\n currency: { key: 'globals.currency', value: 'EUR' },\n },\n },\n include: [],\n },\n out: [\n [\n 'ttq.track',\n 'ViewContent',\n {\n content_type: 'product',\n content_id: 'ers',\n content_name: 'Everyday Ruck Snack',\n // content_category is absent from the default product view fixture;\n // the mapper skips undefined resolutions.\n value: 420,\n currency: 'EUR', // fallback - default fixture has no globals.currency\n },\n { event_id: '11111111aaaaaaaa' },\n ],\n ],\n};\n\n/**\n * Destination-level settings.include flattens the walkerOS `data` section\n * into prefixed TikTok event parameters on every push. This is the\n * \"dump everything\" mode - useful for custom events where TikTok won't\n * do optimization anyway, and no mapping.data is needed.\n */\nexport const destinationLevelInclude: TikTokStepExample = {\n title: 'Include data',\n description:\n 'Destination-level include flattens the event data section into prefixed TikTok event parameters.',\n in: getEvent('product view', { id: '22222222bbbbbbbb' }),\n configInclude: ['data'],\n out: [\n [\n 'ttq.track',\n 'product view',\n {\n data_id: 'ers',\n data_name: 'Everyday Ruck Snack',\n data_color: 'black',\n data_size: 'l',\n data_price: 420,\n },\n { event_id: '22222222bbbbbbbb' },\n ],\n ],\n};\n\n/**\n * Per-rule settings.include REPLACES destination-level include for the\n * matched rule (design doc §6: mapping-level include replaces, not\n * merges with, destination-level include).\n */\nexport const ruleIncludeReplaces: TikTokStepExample = {\n title: 'Rule include overrides',\n description:\n 'A per-rule include replaces the destination-level include so this event forwards only globals.',\n in: getEvent('order complete', { id: '33333333cccccccc' }),\n configInclude: ['data'],\n mapping: {\n include: ['globals'],\n },\n out: [\n [\n 'ttq.track',\n 'order complete',\n {\n globals_pagegroup: 'shop',\n },\n { event_id: '33333333cccccccc' },\n ],\n ],\n};\n\n/**\n * Destination-level settings.identify fires on the first push (once the\n * state cache is empty). Advanced Matching parameters (email,\n * phone_number, external_id) are passed to ttq.identify() which\n * auto-hashes them SHA256 before sending. Subsequent pushes with\n * unchanged values do NOT re-fire ttq.identify() - runtime state tracks\n * the last-resolved identity.\n *\n * walkerOS's default user fixture has user.id='us3r' and no email/phone,\n * so the example injects data and maps from there.\n */\nexport const destinationLevelIdentify: TikTokStepExample = {\n title: 'Advanced matching',\n description:\n 'Destination-level identify calls ttq.identify with email, phone, and external id for TikTok advanced matching.',\n in: getEvent('page view', {\n id: '44444444dddddddd',\n data: {\n email: 'user@acme.com',\n phone: '+14135552671',\n },\n }),\n settings: {\n identify: {\n map: {\n email: 'data.email',\n phone_number: 'data.phone',\n external_id: 'user.id',\n },\n },\n },\n out: [\n [\n 'ttq.identify',\n {\n email: 'user@acme.com',\n phone_number: '+14135552671',\n external_id: 'us3r',\n },\n ],\n ['ttq.track', 'page view', {}, { event_id: '44444444dddddddd' }],\n ],\n};\n\n/**\n * User registration → CompleteRegistration standard event with per-event\n * identify. The user just provided their email + phone, so this is the\n * moment to fire Advanced Matching for this session. The per-event\n * identify overrides any destination-level identify for this one push.\n */\nexport const userRegisterCompleteRegistration: TikTokStepExample = {\n title: 'Complete registration',\n description:\n 'A user register fires ttq.identify for advanced matching and then tracks CompleteRegistration.',\n in: getEvent('user register', {\n id: '55555555eeeeeeee',\n data: {\n email: 'new@acme.com',\n phone: '+14135551234',\n user_id: 'new-user-123',\n },\n }),\n mapping: {\n name: 'CompleteRegistration',\n include: [],\n data: {\n map: {\n content_type: { value: 'product' },\n },\n },\n settings: {\n identify: {\n map: {\n email: 'data.email',\n phone_number: 'data.phone',\n external_id: 'data.user_id',\n },\n },\n },\n },\n out: [\n [\n 'ttq.identify',\n {\n email: 'new@acme.com',\n phone_number: '+14135551234',\n external_id: 'new-user-123',\n },\n ],\n [\n 'ttq.track',\n 'CompleteRegistration',\n {\n content_type: 'product',\n },\n { event_id: '55555555eeeeeeee' },\n ],\n ],\n};\n\n/**\n * Multi-product order → CompletePayment standard event. The canonical\n * TikTok ecommerce pattern:\n * - mapping.name flips the walkerOS event to TikTok's rigid taxonomy\n * - mapping.data builds the TikTok-native parameter shape\n * - loop iterates event.nested to produce the `contents` array, one\n * entry per product\n * - { key, value: 'EUR' } provides a currency fallback if data.currency\n * is absent (here data.currency is 'EUR' so the key wins)\n *\n * The default \"order complete\" fixture has 3 nested entries: two\n * products (ers, cc) and one gift (Surprise - no id, no price).\n */\nexport const orderCompleteCompletePayment: TikTokStepExample = {\n title: 'Complete payment',\n description:\n 'A completed order is mapped to TikTok CompletePayment with value, currency, and nested product contents.',\n in: getEvent('order complete', { id: '66666666ffffffff' }),\n mapping: {\n name: 'CompletePayment',\n data: {\n map: {\n content_type: { value: 'product' },\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n order_id: 'data.id',\n contents: {\n loop: [\n 'nested',\n {\n map: {\n content_id: 'data.id',\n content_name: 'data.name',\n quantity: { key: 'data.quantity', value: 1 },\n price: 'data.price',\n },\n },\n ],\n },\n },\n },\n include: [],\n },\n out: [\n [\n 'ttq.track',\n 'CompletePayment',\n {\n content_type: 'product',\n value: 555,\n currency: 'EUR',\n order_id: '0rd3r1d',\n contents: [\n {\n content_id: 'ers',\n content_name: 'Everyday Ruck Snack',\n quantity: 1, // fallback - fixture has no data.quantity\n price: 420,\n },\n {\n content_id: 'cc',\n content_name: 'Cool Cap',\n quantity: 1,\n price: 42,\n },\n {\n // gift entry - { name: 'Surprise' }, no id and no price.\n // walkerOS map skips keys whose resolved value is undefined.\n content_name: 'Surprise',\n quantity: 1,\n },\n ],\n },\n { event_id: '66666666ffffffff' },\n ],\n ],\n};\n\n/**\n * Search → TikTok Search standard event. Minimal example that shows how\n * a walkerOS search event flips through mapping.name with a single\n * mapping.data field (the query string).\n */\nexport const searchSubmitSearch: TikTokStepExample = {\n title: 'Search',\n description:\n 'A search submit fires TikTok Search with the query field mapped from event data.',\n in: getEvent('search submit', {\n id: '777777770000aaaa',\n data: {\n term: 'hiking backpack',\n },\n }),\n mapping: {\n name: 'Search',\n data: {\n map: {\n query: 'data.term',\n },\n },\n include: [],\n },\n out: [\n [\n 'ttq.track',\n 'Search',\n {\n query: 'hiking backpack',\n },\n { event_id: '777777770000aaaa' },\n ],\n ],\n};\n\n/**\n * Consent granted → ttq.enableCookie(). The destination checks the\n * consent keys declared in config.consent (here \"marketing\" - TikTok is\n * an ad platform, not analytics) and toggles cookie behavior.\n *\n * Uses the canonical StepExample.command='consent' pattern: the test\n * runner dispatches via elb('walker consent', in) instead of pushing\n * an event.\n */\nexport const consentGrantEnableCookie: TikTokStepExample = {\n title: 'Consent granted',\n description:\n 'A walker consent grant for marketing calls ttq.enableCookie so TikTok can set and read its attribution cookie.',\n command: 'consent',\n in: { marketing: true } as WalkerOS.Consent,\n settings: {} as Partial<Settings>, // consent key is derived from config.consent\n out: [['ttq.enableCookie']],\n};\n\n/**\n * Consent revoked → ttq.disableCookie(). TikTok stops setting and\n * reading its first-party cookie (_ttp) for attribution.\n */\nexport const consentRevokeDisableCookie: TikTokStepExample = {\n title: 'Consent revoked',\n description:\n 'A walker consent revoke for marketing calls ttq.disableCookie so TikTok stops using its first-party cookie.',\n command: 'consent',\n before: { marketing: true },\n in: { marketing: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['ttq.enableCookie'], ['ttq.disableCookie']],\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\n .object({\n apiKey: z\n .string()\n .min(1)\n .describe(\n 'Your TikTok Pixel ID. Find it in TikTok Ads Manager under \"Assets\" → \"Events\" → \"Web Events\" → select your pixel → \"Setup Web Event\" → \"Pixel ID\".',\n ),\n // `pageview` removed 2026-04-09 — TikTok's SDK fires auto page view and\n // the knob was unreliable. Let it fire; don't expose a toggle.\n auto_config: z\n .boolean()\n .describe(\n 'TikTok default: true. Enable automatic form field detection for Advanced Matching.',\n )\n .optional(),\n limited_data_use: z\n .boolean()\n .describe(\n 'TikTok default: false. Restrict data use for compliance with U.S. state privacy laws.',\n )\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to an Advanced Matching object with any of: email, phone_number, external_id. All values are auto-hashed (SHA256) by the TikTok SDK before sending.',\n )\n .optional(),\n })\n // Pass-through settings are loose: every other TikTok option is forwarded\n // to ttq.load() as given.\n .loose();\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 Advanced Matching mapping. Resolves to an object with any of: email, phone_number, external_id. Overrides destination-level settings.identify for this rule.',\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 { mockScriptDocument } from '@walkeros/web-core/dev';\nimport type { Env, TTQ } from '../types';\n\nconst noop = () => {};\n\n/** Build a fresh mock ttq: each call returns a new object so tests can mutate independently. */\nfunction makeMockTTQ(): TTQ {\n return Object.assign(() => {}, {\n load: noop,\n page: noop,\n track: noop,\n identify: noop,\n enableCookie: noop,\n disableCookie: noop,\n methods: [\n 'page',\n 'track',\n 'identify',\n 'instances',\n 'debug',\n 'on',\n 'off',\n 'once',\n 'ready',\n 'alias',\n 'group',\n 'enableCookie',\n 'disableCookie',\n ],\n _i: {},\n loaded: true,\n });\n}\n\n/** Minimal web env: window has a mock ttq, document takes the Pixel script. */\nfunction makeEnv(): Env {\n return {\n window: {\n ttq: makeMockTTQ(),\n },\n document: mockScriptDocument(),\n };\n}\n\n/**\n * Pre-init env — destination init() call will set up ttq and load the\n * script. Tests receive this as a starting point.\n */\nexport const init: Env = makeEnv();\n\n/**\n * Post-init env — same shape; the test runner clones this and replaces\n * individual ttq methods with jest.fn() so it can assert on calls.\n */\nexport const push: Env = makeEnv();\n\n/** Simulation tracking paths for CLI --simulate. */\nexport const simulation = [\n 'call:window.ttq.load',\n 'call:window.ttq.track',\n 'call:window.ttq.identify',\n 'call:window.ttq.page',\n 'call:window.ttq.enableCookie',\n 'call:window.ttq.disableCookie',\n];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { createEvent, getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Examples may optionally carry destination-level settings. The test\n * runner reads `settings` from the example and merges it into the base\n * destination settings on top of the fixed apiKey.\n */\nexport type TikTokStepExample = 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 a ttq.track()\n * call. With no mapping and no destination-level include, the params\n * object is empty. event_id is always passed as the 3rd argument (TikTok\n * dedup between pixel and Events API).\n *\n * NOTE: The raw walkerOS event name \"product view\" (with space) is NOT a\n * TikTok standard event. Without a mapping.name override, TikTok treats\n * it as a custom event - functional for audience building, no\n * optimization. The next example shows the recommended override.\n */\nexport const defaultEventForwarding: TikTokStepExample = {\n title: 'Default track',\n description:\n 'Without a mapping the walker event name is forwarded to ttq.track with an event_id for TikTok dedup.',\n in: getEvent('product view', { id: '0123456789abcdef' }),\n out: [['ttq.track', 'product view', {}, { event_id: '0123456789abcdef' }]],\n};\n\n/**\n * Wildcard ignore - walkerOS's standard way to drop events. The rule\n * matches but does nothing. The destination fires zero SDK calls.\n */\nexport const wildcardIgnored: TikTokStepExample = {\n public: false,\n in: getEvent('product view'),\n mapping: { ignore: true },\n out: [],\n};\n\n/**\n * The canonical TikTok pattern: walkerOS \"product view\" → TikTok\n * \"ViewContent\" via mapping.name. mapping.data builds the TikTok-native\n * parameter shape (content_type, content_id, content_name, value,\n * currency). include is explicitly set to [] so prefixed walkerOS\n * properties don't leak onto the call and confuse TikTok's matcher.\n */\nexport const productViewContent: TikTokStepExample = {\n title: 'View content',\n description:\n 'A product view is renamed to the TikTok ViewContent standard event with content_type, id, value, and currency.',\n in: getEvent('product view', { id: '11111111aaaaaaaa' }),\n mapping: {\n name: 'ViewContent',\n data: {\n map: {\n content_type: { value: 'product' },\n content_id: 'data.id',\n content_name: 'data.name',\n content_category: 'data.category',\n value: 'data.price',\n currency: { key: 'globals.currency', value: 'EUR' },\n },\n },\n include: [],\n },\n out: [\n [\n 'ttq.track',\n 'ViewContent',\n {\n content_type: 'product',\n content_id: 'ers',\n content_name: 'Everyday Ruck Snack',\n // content_category is absent from the default product view fixture;\n // the mapper skips undefined resolutions.\n value: 420,\n currency: 'EUR', // fallback - default fixture has no globals.currency\n },\n { event_id: '11111111aaaaaaaa' },\n ],\n ],\n};\n\n/**\n * Destination-level settings.include flattens the walkerOS `data` section\n * into prefixed TikTok event parameters on every push. This is the\n * \"dump everything\" mode - useful for custom events where TikTok won't\n * do optimization anyway, and no mapping.data is needed.\n */\nexport const destinationLevelInclude: TikTokStepExample = {\n title: 'Include data',\n description:\n 'Destination-level include flattens the event data section into prefixed TikTok event parameters.',\n in: getEvent('product view', { id: '22222222bbbbbbbb' }),\n configInclude: ['data'],\n out: [\n [\n 'ttq.track',\n 'product view',\n {\n data_id: 'ers',\n data_name: 'Everyday Ruck Snack',\n data_color: 'black',\n data_size: 'l',\n data_price: 420,\n },\n { event_id: '22222222bbbbbbbb' },\n ],\n ],\n};\n\n/**\n * Per-rule settings.include REPLACES destination-level include for the\n * matched rule (design doc §6: mapping-level include replaces, not\n * merges with, destination-level include).\n */\nexport const ruleIncludeReplaces: TikTokStepExample = {\n title: 'Rule include overrides',\n description:\n 'A per-rule include replaces the destination-level include so this event forwards only globals.',\n in: getEvent('order complete', { id: '33333333cccccccc' }),\n configInclude: ['data'],\n mapping: {\n include: ['globals'],\n },\n out: [\n [\n 'ttq.track',\n 'order complete',\n {\n globals_pagegroup: 'shop',\n },\n { event_id: '33333333cccccccc' },\n ],\n ],\n};\n\n/**\n * Destination-level settings.identify fires on the first push (once the\n * state cache is empty). Advanced Matching parameters (email,\n * phone_number, external_id) are passed to ttq.identify() which\n * auto-hashes them SHA256 before sending. Subsequent pushes with\n * unchanged values do NOT re-fire ttq.identify() - runtime state tracks\n * the last-resolved identity.\n *\n * walkerOS's default user fixture has user.id='us3r' and no email/phone,\n * so the example injects data and maps from there.\n */\nexport const destinationLevelIdentify: TikTokStepExample = {\n title: 'Advanced matching',\n description:\n 'Destination-level identify calls ttq.identify with email, phone, and external id for TikTok advanced matching.',\n in: getEvent('page view', {\n id: '44444444dddddddd',\n data: {\n email: 'user@acme.com',\n phone: '+14135552671',\n },\n }),\n settings: {\n identify: {\n map: {\n email: 'data.email',\n phone_number: 'data.phone',\n external_id: 'user.id',\n },\n },\n },\n out: [\n [\n 'ttq.identify',\n {\n email: 'user@acme.com',\n phone_number: '+14135552671',\n external_id: 'us3r',\n },\n ],\n ['ttq.track', 'page view', {}, { event_id: '44444444dddddddd' }],\n ],\n};\n\n/**\n * User registration → CompleteRegistration standard event with per-event\n * identify. The user just provided their email + phone, so this is the\n * moment to fire Advanced Matching for this session. The per-event\n * identify overrides any destination-level identify for this one push.\n */\nexport const userRegisterCompleteRegistration: TikTokStepExample = {\n title: 'Complete registration',\n description:\n 'A user register fires ttq.identify for advanced matching and then tracks CompleteRegistration.',\n in: createEvent({\n name: 'user register',\n id: '55555555eeeeeeee',\n data: {\n email: 'new@acme.com',\n phone: '+14135551234',\n user_id: 'new-user-123',\n },\n }),\n mapping: {\n name: 'CompleteRegistration',\n include: [],\n data: {\n map: {\n content_type: { value: 'product' },\n },\n },\n settings: {\n identify: {\n map: {\n email: 'data.email',\n phone_number: 'data.phone',\n external_id: 'data.user_id',\n },\n },\n },\n },\n out: [\n [\n 'ttq.identify',\n {\n email: 'new@acme.com',\n phone_number: '+14135551234',\n external_id: 'new-user-123',\n },\n ],\n [\n 'ttq.track',\n 'CompleteRegistration',\n {\n content_type: 'product',\n },\n { event_id: '55555555eeeeeeee' },\n ],\n ],\n};\n\n/**\n * Multi-product order → CompletePayment standard event. The canonical\n * TikTok ecommerce pattern:\n * - mapping.name flips the walkerOS event to TikTok's rigid taxonomy\n * - mapping.data builds the TikTok-native parameter shape\n * - loop iterates event.nested to produce the `contents` array, one\n * entry per product\n * - { key, value: 'EUR' } provides a currency fallback if data.currency\n * is absent (here data.currency is 'EUR' so the key wins)\n *\n * The default \"order complete\" fixture has 3 nested entries: two\n * products (ers, cc) and one gift (Surprise - no id, no price).\n */\nexport const orderCompleteCompletePayment: TikTokStepExample = {\n title: 'Complete payment',\n description:\n 'A completed order is mapped to TikTok CompletePayment with value, currency, and nested product contents.',\n in: getEvent('order complete', { id: '66666666ffffffff' }),\n mapping: {\n name: 'CompletePayment',\n data: {\n map: {\n content_type: { value: 'product' },\n value: 'data.value',\n currency: { key: 'data.currency', value: 'EUR' },\n order_id: 'data.id',\n contents: {\n loop: [\n 'nested',\n {\n map: {\n content_id: 'data.id',\n content_name: 'data.name',\n quantity: { key: 'data.quantity', value: 1 },\n price: 'data.price',\n },\n },\n ],\n },\n },\n },\n include: [],\n },\n out: [\n [\n 'ttq.track',\n 'CompletePayment',\n {\n content_type: 'product',\n value: 555,\n currency: 'EUR',\n order_id: '0rd3r1d',\n contents: [\n {\n content_id: 'ers',\n content_name: 'Everyday Ruck Snack',\n quantity: 1, // fallback - fixture has no data.quantity\n price: 420,\n },\n {\n content_id: 'cc',\n content_name: 'Cool Cap',\n quantity: 1,\n price: 42,\n },\n {\n // gift entry - { name: 'Surprise' }, no id and no price.\n // walkerOS map skips keys whose resolved value is undefined.\n content_name: 'Surprise',\n quantity: 1,\n },\n ],\n },\n { event_id: '66666666ffffffff' },\n ],\n ],\n};\n\n/**\n * Search → TikTok Search standard event. Minimal example that shows how\n * a walkerOS search event flips through mapping.name with a single\n * mapping.data field (the query string).\n */\nexport const searchSubmitSearch: TikTokStepExample = {\n title: 'Search',\n description:\n 'A search submit fires TikTok Search with the query field mapped from event data.',\n in: createEvent({\n name: 'search submit',\n id: '777777770000aaaa',\n data: {\n term: 'hiking backpack',\n },\n }),\n mapping: {\n name: 'Search',\n data: {\n map: {\n query: 'data.term',\n },\n },\n include: [],\n },\n out: [\n [\n 'ttq.track',\n 'Search',\n {\n query: 'hiking backpack',\n },\n { event_id: '777777770000aaaa' },\n ],\n ],\n};\n\n/**\n * Consent granted → ttq.enableCookie(). The destination checks the\n * consent keys declared in config.consent (here \"marketing\" - TikTok is\n * an ad platform, not analytics) and toggles cookie behavior.\n *\n * Uses the canonical StepExample.command='consent' pattern: the test\n * runner dispatches via elb('walker consent', in) instead of pushing\n * an event.\n */\nexport const consentGrantEnableCookie: TikTokStepExample = {\n title: 'Consent granted',\n description:\n 'A walker consent grant for marketing calls ttq.enableCookie so TikTok can set and read its attribution cookie.',\n command: 'consent',\n in: { marketing: true } as WalkerOS.Consent,\n settings: {} as Partial<Settings>, // consent key is derived from config.consent\n out: [['ttq.enableCookie']],\n};\n\n/**\n * Consent revoked → ttq.disableCookie(). TikTok stops setting and\n * reading its first-party cookie (_ttp) for attribution.\n */\nexport const consentRevokeDisableCookie: TikTokStepExample = {\n title: 'Consent revoked',\n description:\n 'A walker consent revoke for marketing calls ttq.disableCookie so TikTok stops using its first-party cookie.',\n command: 'consent',\n before: { marketing: true },\n in: { marketing: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['window.ttq.disableCookie']],\n};\n\n/** A silent rule sends no track call. */\nexport const silentRule: TikTokStepExample = {\n public: false,\n description: 'A rule with silent: true sends no ttq.track call.',\n in: getEvent('page view', { timestamp: 1700000600 }),\n mapping: { silent: true },\n out: [],\n};\n\n/**\n * A silent rule that only sets an identity, on an event with no email, phone\n * or id: nothing resolves and the rule suppresses the track, so nothing is\n * sent. A declared skip: an unmet mapping, not a failure.\n */\nexport const silentIdentifyWithoutData: TikTokStepExample = {\n public: false,\n description:\n 'A silent rule whose identify mapping finds no email, phone or id sends nothing: an unmet mapping, not a failure, so the push returns normally.',\n in: { name: 'user update', entity: 'user', action: 'update' },\n mapping: {\n silent: true,\n settings: {\n identify: {\n map: {\n email: 'data.email',\n phone_number: 'data.phone',\n external_id: 'data.id',\n },\n },\n },\n },\n out: [],\n};\n"],"mappings":"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","names":["z"]}
|
|
@@ -84,12 +84,20 @@ interface Env extends DestinationWeb.Env {
|
|
|
84
84
|
window: {
|
|
85
85
|
ttq: TTQ;
|
|
86
86
|
};
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The queue `setup()` installs until the Pixel script replaces it: each
|
|
90
|
+
* call is kept in `_i.all`.
|
|
91
|
+
*/
|
|
92
|
+
type TTQStub = ((...args: unknown[]) => void) & {
|
|
93
|
+
methods: string[];
|
|
94
|
+
_i: Record<string, unknown[]>;
|
|
95
|
+
loaded: boolean;
|
|
96
|
+
};
|
|
97
|
+
declare global {
|
|
98
|
+
interface Window {
|
|
99
|
+
ttq?: TTQ | TTQStub;
|
|
100
|
+
}
|
|
93
101
|
}
|
|
94
102
|
|
|
95
103
|
/**
|
|
@@ -215,6 +223,14 @@ declare const consentGrantEnableCookie: TikTokStepExample;
|
|
|
215
223
|
* reading its first-party cookie (_ttp) for attribution.
|
|
216
224
|
*/
|
|
217
225
|
declare const consentRevokeDisableCookie: TikTokStepExample;
|
|
226
|
+
/** A silent rule sends no track call. */
|
|
227
|
+
declare const silentRule: TikTokStepExample;
|
|
228
|
+
/**
|
|
229
|
+
* A silent rule that only sets an identity, on an event with no email, phone
|
|
230
|
+
* or id: nothing resolves and the rule suppresses the track, so nothing is
|
|
231
|
+
* sent. A declared skip: an unmet mapping, not a failure.
|
|
232
|
+
*/
|
|
233
|
+
declare const silentIdentifyWithoutData: TikTokStepExample;
|
|
218
234
|
|
|
219
235
|
type step_TikTokStepExample = TikTokStepExample;
|
|
220
236
|
declare const step_consentGrantEnableCookie: typeof consentGrantEnableCookie;
|
|
@@ -226,10 +242,12 @@ declare const step_orderCompleteCompletePayment: typeof orderCompleteCompletePay
|
|
|
226
242
|
declare const step_productViewContent: typeof productViewContent;
|
|
227
243
|
declare const step_ruleIncludeReplaces: typeof ruleIncludeReplaces;
|
|
228
244
|
declare const step_searchSubmitSearch: typeof searchSubmitSearch;
|
|
245
|
+
declare const step_silentIdentifyWithoutData: typeof silentIdentifyWithoutData;
|
|
246
|
+
declare const step_silentRule: typeof silentRule;
|
|
229
247
|
declare const step_userRegisterCompleteRegistration: typeof userRegisterCompleteRegistration;
|
|
230
248
|
declare const step_wildcardIgnored: typeof wildcardIgnored;
|
|
231
249
|
declare namespace step {
|
|
232
|
-
export { type step_TikTokStepExample as TikTokStepExample, step_consentGrantEnableCookie as consentGrantEnableCookie, step_consentRevokeDisableCookie as consentRevokeDisableCookie, step_defaultEventForwarding as defaultEventForwarding, step_destinationLevelIdentify as destinationLevelIdentify, step_destinationLevelInclude as destinationLevelInclude, step_orderCompleteCompletePayment as orderCompleteCompletePayment, step_productViewContent as productViewContent, step_ruleIncludeReplaces as ruleIncludeReplaces, step_searchSubmitSearch as searchSubmitSearch, step_userRegisterCompleteRegistration as userRegisterCompleteRegistration, step_wildcardIgnored as wildcardIgnored };
|
|
250
|
+
export { type step_TikTokStepExample as TikTokStepExample, step_consentGrantEnableCookie as consentGrantEnableCookie, step_consentRevokeDisableCookie as consentRevokeDisableCookie, step_defaultEventForwarding as defaultEventForwarding, step_destinationLevelIdentify as destinationLevelIdentify, step_destinationLevelInclude as destinationLevelInclude, step_orderCompleteCompletePayment as orderCompleteCompletePayment, step_productViewContent as productViewContent, step_ruleIncludeReplaces as ruleIncludeReplaces, step_searchSubmitSearch as searchSubmitSearch, step_silentIdentifyWithoutData as silentIdentifyWithoutData, step_silentRule as silentRule, step_userRegisterCompleteRegistration as userRegisterCompleteRegistration, step_wildcardIgnored as wildcardIgnored };
|
|
233
251
|
}
|
|
234
252
|
|
|
235
253
|
export { env, step };
|