@getvitops/utils 8.1.0 → 8.2.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +264 -8
- package/dist/{adc-BFrzpMHq.d.mts → adc-BoEoogyo.d.mts} +2 -3
- package/dist/adc-BoEoogyo.d.mts.map +1 -0
- package/dist/ads/index.d.mts +50 -17
- package/dist/ads/index.d.mts.map +1 -1
- package/dist/ads/index.mjs +75 -7
- package/dist/ads/index.mjs.map +1 -1
- package/dist/cloudflare-BiK61Oq4.d.mts.map +1 -1
- package/dist/color/index.d.mts +34 -35
- package/dist/color/index.d.mts.map +1 -1
- package/dist/color/index.mjs +3 -1
- package/dist/color/index.mjs.map +1 -1
- package/dist/crm/index.d.mts +288 -0
- package/dist/crm/index.d.mts.map +1 -0
- package/dist/crm/index.mjs +731 -0
- package/dist/crm/index.mjs.map +1 -0
- package/dist/email/index.d.mts +216 -0
- package/dist/email/index.d.mts.map +1 -0
- package/dist/email/index.mjs +331 -0
- package/dist/email/index.mjs.map +1 -0
- package/dist/favicon.d.mts +8 -9
- package/dist/favicon.d.mts.map +1 -1
- package/dist/git/index.d.mts +65 -0
- package/dist/git/index.d.mts.map +1 -0
- package/dist/git/index.mjs +107 -0
- package/dist/git/index.mjs.map +1 -0
- package/dist/hosting/index.d.mts +29 -29
- package/dist/hosting/index.d.mts.map +1 -1
- package/dist/hosting/index.mjs +7 -4
- package/dist/hosting/index.mjs.map +1 -1
- package/dist/identity-BoRddTx3.mjs +35 -0
- package/dist/identity-BoRddTx3.mjs.map +1 -0
- package/dist/index.d.mts +24 -25
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +5 -5
- package/dist/index.mjs.map +1 -1
- package/dist/indexing/index.d.mts +23 -24
- package/dist/indexing/index.d.mts.map +1 -1
- package/dist/media/index.d.mts +24 -24
- package/dist/media/index.d.mts.map +1 -1
- package/dist/media/index.mjs +3 -3
- package/dist/media/index.mjs.map +1 -1
- package/dist/notify/index.d.mts +26 -15
- package/dist/notify/index.d.mts.map +1 -1
- package/dist/notify/index.mjs +50 -20
- package/dist/notify/index.mjs.map +1 -1
- package/dist/onboarding/index.d.mts +10 -141
- package/dist/onboarding/index.d.mts.map +1 -1
- package/dist/onboarding/index.mjs +1 -144
- package/dist/onboarding/index.mjs.map +1 -1
- package/dist/plan-BLKikoOG.mjs +150 -0
- package/dist/plan-BLKikoOG.mjs.map +1 -0
- package/dist/plan-Hq8Pb0Uw.d.mts +133 -0
- package/dist/plan-Hq8Pb0Uw.d.mts.map +1 -0
- package/dist/reviews/index.d.mts +12 -13
- package/dist/reviews/index.d.mts.map +1 -1
- package/dist/schema/index.d.mts +7 -7
- package/dist/schema/index.d.mts.map +1 -1
- package/dist/security/index.d.mts +2 -2
- package/dist/security/index.d.mts.map +1 -1
- package/dist/{token-Bz_-igw-.d.mts → token-DmmoQ7um.d.mts} +6 -3
- package/dist/token-DmmoQ7um.d.mts.map +1 -0
- package/dist/tracking/index.d.mts +43 -17
- package/dist/tracking/index.d.mts.map +1 -1
- package/dist/tracking/index.mjs +2 -1
- package/dist/tracking/index.mjs.map +1 -1
- package/dist/{types-CHHjzRrv.d.mts → types-7ELci8RQ.d.mts} +4 -2
- package/dist/types-7ELci8RQ.d.mts.map +1 -0
- package/package.json +14 -4
- package/dist/adc-BFrzpMHq.d.mts.map +0 -1
- package/dist/token-Bz_-igw-.d.mts.map +0 -1
- package/dist/types-CHHjzRrv.d.mts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/tracking/cookie.ts"],"sourcesContent":["/**\n * Reading and writing the `_ac` cookie, as functions over a cookie **string**.\n *\n * String in, string out, so one implementation serves both ends: the browser\n * passes `document.cookie`, the conversion handler passes the request's `Cookie`\n * header. A separate server-side parser would be a second thing to keep in step\n * with the writer, and the failure — attribution silently absent from a\n * notification — looks identical to a visitor who arrived organically.\n *\n * The same shape, for the same reason, as `@getvitops/core`'s consent store.\n */\nimport { TRACKING_COOKIE, TRACKING_COOKIE_DAYS } from './params.ts';\nimport type { TrackingData } from './types.ts';\n\n/** Read one cookie out of a `document.cookie`-shaped string. */\nexport function readCookie(cookieString: string | null | undefined, name: string): string | null {\n if (!cookieString) return null;\n for (const part of cookieString.split(';')) {\n const raw = part.trim();\n if (raw.slice(0, name.length + 1) === `${name}=`) return raw.slice(name.length + 1);\n }\n return null;\n}\n\n/**\n * Cookie header → attribution, or `null`.\n *\n * Anything unparseable reads as `null` — no attribution — rather than as a\n * partial record. A half-read cookie would attribute a conversion to whichever\n * fields happened to survive, which is worse than reporting it unattributed:\n * \"we don't know\" is actionable, a wrong campaign is not.\n */\nexport function parseTrackingCookie(cookieHeader: string | null | undefined): TrackingData | null {\n const raw = readCookie(cookieHeader, TRACKING_COOKIE);\n if (!raw) return null;\n try {\n const data: unknown = JSON.parse(decodeURIComponent(raw));\n if (typeof data !== 'object' || data === null || Array.isArray(data)) return null;\n return data as TrackingData;\n } catch {\n return null;\n }\n}\n\n/** Attribution → cookie value (not the full `Set-Cookie` — see `cookieAttributes`). */\nexport function serializeTrackingCookie(data: TrackingData): string {\n // Undefined values would serialize as absent keys anyway; dropping them first\n // keeps the cookie small and the round-trip exact.\n const clean = Object.fromEntries(Object.entries(data).filter(([, v]) => v !== undefined));\n return encodeURIComponent(JSON.stringify(clean));\n}\n\n/**\n * Attributes for the attribution cookie.\n *\n * `SameSite=Lax` rather than `Strict`: the visitor arrives here by following a\n * link from the ad platform, and `Strict` withholds the cookie on exactly that\n * cross-site navigation — so a returning click would read as a fresh one. No\n * `HttpOnly`, because the capture script has to write it from the page.\n */\nexport function cookieAttributes(now: number, secure: boolean): string {\n const expires = new Date(now + TRACKING_COOKIE_DAYS * 864e5).toUTCString();\n return `;expires=${expires};path=/;SameSite=Lax${secure ? ';Secure' : ''}`;\n}\n\n/**\n * Fold a fresh capture into whatever was already stored.\n *\n * New values win, but `ts` is the **first** capture's — it dates the visitor's\n * original arrival, which is what a 90-day attribution window is measured from.\n * Taking the latest would restart the window on every visit and make the cookie\n * outlive the click it represents.\n */\nexport function mergeTracking(\n existing: TrackingData | null,\n captured: TrackingData,\n now: number,\n): TrackingData {\n return { ...existing, ...captured, ts: existing?.ts ?? now };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/tracking/cookie.ts"],"sourcesContent":["/**\n * Reading and writing the `_ac` cookie, as functions over a cookie **string**.\n *\n * String in, string out, so one implementation serves both ends: the browser\n * passes `document.cookie`, the conversion handler passes the request's `Cookie`\n * header. A separate server-side parser would be a second thing to keep in step\n * with the writer, and the failure — attribution silently absent from a\n * notification — looks identical to a visitor who arrived organically.\n *\n * The same shape, for the same reason, as `@getvitops/core`'s consent store.\n */\nimport { TRACKING_COOKIE, TRACKING_COOKIE_DAYS } from './params.ts';\nimport type { TrackingData } from './types.ts';\n\n/** Read one cookie out of a `document.cookie`-shaped string. */\nexport function readCookie(cookieString: string | null | undefined, name: string): string | null {\n if (!cookieString) return null;\n for (const part of cookieString.split(';')) {\n const raw = part.trim();\n if (raw.slice(0, name.length + 1) === `${name}=`) return raw.slice(name.length + 1);\n }\n return null;\n}\n\n/**\n * Cookie header → attribution, or `null`.\n *\n * Anything unparseable reads as `null` — no attribution — rather than as a\n * partial record. A half-read cookie would attribute a conversion to whichever\n * fields happened to survive, which is worse than reporting it unattributed:\n * \"we don't know\" is actionable, a wrong campaign is not.\n */\nexport function parseTrackingCookie(cookieHeader: string | null | undefined): TrackingData | null {\n const raw = readCookie(cookieHeader, TRACKING_COOKIE);\n if (!raw) return null;\n try {\n const data: unknown = JSON.parse(decodeURIComponent(raw));\n if (typeof data !== 'object' || data === null || Array.isArray(data)) return null;\n return data as TrackingData;\n } catch {\n return null;\n }\n}\n\n/** Attribution → cookie value (not the full `Set-Cookie` — see `cookieAttributes`). */\nexport function serializeTrackingCookie(data: TrackingData): string {\n // Undefined values would serialize as absent keys anyway; dropping them first\n // keeps the cookie small and the round-trip exact.\n const clean = Object.fromEntries(Object.entries(data).filter(([, v]) => v !== undefined));\n return encodeURIComponent(JSON.stringify(clean));\n}\n\n/**\n * Attributes for the attribution cookie.\n *\n * `SameSite=Lax` rather than `Strict`: the visitor arrives here by following a\n * link from the ad platform, and `Strict` withholds the cookie on exactly that\n * cross-site navigation — so a returning click would read as a fresh one. No\n * `HttpOnly`, because the capture script has to write it from the page.\n */\nexport function cookieAttributes(now: number, secure: boolean): string {\n const expires = new Date(now + TRACKING_COOKIE_DAYS * 864e5).toUTCString();\n return `;expires=${expires};path=/;SameSite=Lax${secure ? ';Secure' : ''}`;\n}\n\n/**\n * Fold a fresh capture into whatever was already stored.\n *\n * New values win, but `ts` is the **first** capture's — it dates the visitor's\n * original arrival, which is what a 90-day attribution window is measured from.\n * Taking the latest would restart the window on every visit and make the cookie\n * outlive the click it represents.\n */\nexport function mergeTracking(\n existing: TrackingData | null,\n captured: TrackingData,\n now: number,\n): TrackingData {\n return { ...existing, ...captured, ts: existing?.ts ?? now };\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,SAAgB,WAAW,cAAyC,MAA6B;CAC/F,IAAI,CAAC,cAAc,OAAO;CAC1B,KAAK,MAAM,QAAQ,aAAa,MAAM,GAAG,GAAG;EAC1C,MAAM,MAAM,KAAK,KAAK;EACtB,IAAI,IAAI,MAAM,GAAG,KAAK,SAAS,CAAC,MAAM,GAAG,KAAK,IAAI,OAAO,IAAI,MAAM,KAAK,SAAS,CAAC;CACpF;CACA,OAAO;AACT;;;;;;;;;AAUA,SAAgB,oBAAoB,cAA8D;CAChG,MAAM,MAAM,WAAW,mBAA6B;CACpD,IAAI,CAAC,KAAK,OAAO;CACjB,IAAI;EACF,MAAM,OAAgB,KAAK,MAAM,mBAAmB,GAAG,CAAC;EACxD,IAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,GAAG,OAAO;EAC7E,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF;;AAGA,SAAgB,wBAAwB,MAA4B;CAGlE,MAAM,QAAQ,OAAO,YAAY,OAAO,QAAQ,IAAI,CAAC,CAAC,QAAQ,GAAG,OAAO,MAAM,MAAS,CAAC;CACxF,OAAO,mBAAmB,KAAK,UAAU,KAAK,CAAC;AACjD;;;;;;;;;AAUA,SAAgB,iBAAiB,KAAa,QAAyB;CAErE,OAAO,YADS,IAAI,KAAK,WAA6B,KAAK,CAAC,CAAC,YACpC,EAAE,sBAAsB,SAAS,YAAY;AACxE;;;;;;;;;AAUA,SAAgB,cACd,UACA,UACA,KACc;CACd,OAAO;EAAE,GAAG;EAAU,GAAG;EAAU,IAAI,UAAU,MAAM;CAAI;AAC7D"}
|
|
@@ -52,10 +52,12 @@ interface TrackingData {
|
|
|
52
52
|
* and their tests need no fake timers.
|
|
53
53
|
*/
|
|
54
54
|
interface ConversionEvent {
|
|
55
|
-
type: 'form' | 'call';
|
|
55
|
+
type: 'form' | 'call' | 'email';
|
|
56
56
|
/** Submitted fields, for `type: 'form'`. Honeypots are stripped before this. */
|
|
57
57
|
formData?: Record<string, string> | undefined;
|
|
58
58
|
phone?: string | undefined;
|
|
59
|
+
/** The `mailto:` address, for `type: 'email'`. */
|
|
60
|
+
email?: string | undefined;
|
|
59
61
|
/** Attribution from the `_ac` cookie, or null when the visitor arrived cold. */
|
|
60
62
|
tracking: TrackingData | null;
|
|
61
63
|
userAgent?: string | undefined;
|
|
@@ -65,4 +67,4 @@ interface ConversionEvent {
|
|
|
65
67
|
}
|
|
66
68
|
//#endregion
|
|
67
69
|
export { TrackingData as i, TrackingCategory as n, TrackingConfig as r, ConversionEvent as t };
|
|
68
|
-
//# sourceMappingURL=types-
|
|
70
|
+
//# sourceMappingURL=types-7ELci8RQ.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types-7ELci8RQ.d.mts","names":[],"sources":["../src/tracking/types.ts"],"mappings":";;;;;;;;;;KAiBY;UAEK;EACf;;;;;;;EAOA,WAAW;EACX;;;;;;;;;;UAWe;GACd;;EAED;;EAEA;;EAEA;;EAEA;;;;;;;;;;;;;;UAee;EACf;;EAEA,WAAW;EACX;;EAEA;;EAEA,UAAU;EACV;EACA;;EAEA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getvitops/utils",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.2.0-alpha.0",
|
|
4
4
|
"description": "Shared build-time utilities for the Vitops toolchain — favicon generation and friends.",
|
|
5
5
|
"homepage": "https://docs.vitops.ca",
|
|
6
6
|
"bugs": "https://github.com/getvitops/design-system/issues",
|
|
@@ -54,6 +54,10 @@
|
|
|
54
54
|
"types": "./dist/notify/index.d.mts",
|
|
55
55
|
"import": "./dist/notify/index.mjs"
|
|
56
56
|
},
|
|
57
|
+
"./crm": {
|
|
58
|
+
"types": "./dist/crm/index.d.mts",
|
|
59
|
+
"import": "./dist/crm/index.mjs"
|
|
60
|
+
},
|
|
57
61
|
"./tracking": {
|
|
58
62
|
"types": "./dist/tracking/index.d.mts",
|
|
59
63
|
"import": "./dist/tracking/index.mjs"
|
|
@@ -69,6 +73,14 @@
|
|
|
69
73
|
"./hosting": {
|
|
70
74
|
"types": "./dist/hosting/index.d.mts",
|
|
71
75
|
"import": "./dist/hosting/index.mjs"
|
|
76
|
+
},
|
|
77
|
+
"./email": {
|
|
78
|
+
"types": "./dist/email/index.d.mts",
|
|
79
|
+
"import": "./dist/email/index.mjs"
|
|
80
|
+
},
|
|
81
|
+
"./git": {
|
|
82
|
+
"types": "./dist/git/index.d.mts",
|
|
83
|
+
"import": "./dist/git/index.mjs"
|
|
72
84
|
}
|
|
73
85
|
},
|
|
74
86
|
"publishConfig": {
|
|
@@ -80,9 +92,7 @@
|
|
|
80
92
|
"png-to-ico": "^3.0.2",
|
|
81
93
|
"sharp": "^0.35.3"
|
|
82
94
|
},
|
|
83
|
-
"devDependencies": {
|
|
84
|
-
"vitest": "4.1.9"
|
|
85
|
-
},
|
|
95
|
+
"devDependencies": {},
|
|
86
96
|
"engines": {
|
|
87
97
|
"node": ">=24"
|
|
88
98
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adc-BFrzpMHq.d.mts","names":[],"sources":["../src/google/adc.ts"],"mappings":";;;;iBAkBgB,YAAA,CAAa,GAAA,WAAc,WAAW;;iBAwBtC,eAAA,CAAgB,GAAW;;;;;;AAsB1C;;;;iBALe,kBAAA,CAAmB,IAAA;EACjC,GAAA,EAAK,MAAM;EACX,QAAA;EACA,IAAA;EACA,IAAA,MAAU,KAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"token-Bz_-igw-.d.mts","names":[],"sources":["../src/google/token.ts"],"mappings":";;UAkCiB,cAAA;EACf,YAAA;EACA,WAAW;AAAA;AAAA;AAAA,UAII,WAAA;EACf,QAAA;EACA,YAAA;EACA,YAAA;AAAA;;;;AAAY;AAWd;;;;KAAY,gBAAA;EACN,IAAA;EAAyB,OAAA,EAAS,cAAA;EAAgB,KAAA;AAAA;EAClD,IAAA;EAAe,KAAA,EAAO,WAAW;AAAA;AAAA;AA8CvC;;;;;;;;AA9CuC,iBA8CvB,iBAAA,CACd,UAAA,EAAY,gBAAA,EACZ,SAAA,UAAkB,KAAA,EAClB,GAAA,YACC,OAAA;;;;;;;AAAO;AA6BV;;;;AAEc;AAUd;UAZiB,UAAA;EACf,KAAA;EACA,YAAY;AAAA;AAad;;;;;;;AAAA,KAHY,cAAA,YAA0B,UAAU;;iBAGhC,aAAA,CACd,IAAA,EAAM,cAAA,EACN,KAAA,GAAQ,MAAA,mBACP,MAAA;;cA2BU,MAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types-CHHjzRrv.d.mts","names":[],"sources":["../src/tracking/types.ts"],"mappings":";;AAiBA;;;;AAA4B;AAE5B;;;KAFY,gBAAA;AAAA,UAEK,cAAA;EACf,OAAA;EAOW;;;AACF;AAWX;;EAZE,QAAA,GAAW,gBAAgB;EAC3B,SAAA;AAAA;;;;;;AAoBU;AAeZ;;UAxBiB,YAAA;EAAA,CACd,KAAA;EAwBD;EAtBA,WAAA;EAwBW;EAtBX,QAAA;EAyBA;EAvBA,EAAA;EAwBA;EAtBA,UAAA;AAAA;;AAyBE;;;;;;;;;;;UAVa,eAAA;EACf,IAAA;;EAEA,QAAA,GAAW,MAAA;EACX,KAAA;;EAEA,QAAA,EAAU,YAAY;EACtB,SAAA;EACA,EAAA;;EAEA,EAAA;AAAA"}
|