@windstream/react-shared-components 0.1.94 → 0.1.95
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/README.md +635 -635
- package/dist/contentful/index.esm.js +3 -3
- package/dist/contentful/index.esm.js.map +1 -1
- package/dist/contentful/index.js +3 -3
- package/dist/contentful/index.js.map +1 -1
- package/dist/core.d.ts +4 -4
- package/dist/index.esm.js +5 -13
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +5 -13
- package/dist/index.js.map +1 -1
- package/dist/next/index.esm.js +2 -2
- package/dist/next/index.esm.js.map +1 -1
- package/dist/next/index.js +2 -2
- package/dist/next/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/utils/index.esm.js +1 -1
- package/dist/utils/index.esm.js.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +191 -191
- package/src/components/accordion/Accordion.stories.tsx +230 -230
- package/src/components/accordion/index.test.tsx +270 -270
- package/src/components/accordion/index.tsx +70 -70
- package/src/components/accordion/types.ts +12 -12
- package/src/components/alert-card/AlertCard.stories.tsx +171 -171
- package/src/components/alert-card/index.test.tsx +152 -152
- package/src/components/alert-card/index.tsx +41 -41
- package/src/components/alert-card/types.ts +13 -13
- package/src/components/animation-wrapper/index.test.tsx +424 -424
- package/src/components/animation-wrapper/index.tsx +129 -129
- package/src/components/animation-wrapper/types.ts +11 -11
- package/src/components/brand-button/BrandButton.stories.tsx +223 -223
- package/src/components/brand-button/helpers.ts +35 -35
- package/src/components/brand-button/index.test.tsx +292 -292
- package/src/components/brand-button/index.tsx +120 -120
- package/src/components/brand-button/types.ts +38 -38
- package/src/components/button/Button.stories.tsx +108 -108
- package/src/components/button/index.test.tsx +91 -91
- package/src/components/button/index.tsx +27 -27
- package/src/components/button/types.ts +14 -14
- package/src/components/call-button/CallButton.stories.tsx +324 -324
- package/src/components/call-button/index.test.tsx +260 -260
- package/src/components/call-button/index.tsx +106 -106
- package/src/components/call-button/types.ts +16 -16
- package/src/components/checkbox/Checkbox.stories.tsx +247 -247
- package/src/components/checkbox/index.test.tsx +252 -252
- package/src/components/checkbox/index.tsx +197 -197
- package/src/components/checkbox/types.ts +27 -27
- package/src/components/checklist/Checklist.stories.tsx +150 -150
- package/src/components/checklist/index.test.tsx +231 -231
- package/src/components/checklist/index.tsx +96 -96
- package/src/components/checklist/types.ts +23 -23
- package/src/components/collapse/Collapse.stories.tsx +255 -255
- package/src/components/collapse/index.test.tsx +277 -277
- package/src/components/collapse/index.tsx +47 -47
- package/src/components/collapse/types.ts +6 -6
- package/src/components/divider/Divider.stories.tsx +205 -205
- package/src/components/divider/index.test.tsx +53 -53
- package/src/components/divider/index.tsx +22 -22
- package/src/components/divider/type.ts +3 -3
- package/src/components/image/Image.stories.tsx +113 -113
- package/src/components/image/index.test.tsx +174 -174
- package/src/components/image/index.tsx +25 -25
- package/src/components/image/types.ts +40 -40
- package/src/components/input/Input.stories.tsx +325 -325
- package/src/components/input/index.test.tsx +348 -348
- package/src/components/input/index.tsx +177 -177
- package/src/components/input/types.ts +37 -37
- package/src/components/link/Link.stories.tsx +163 -163
- package/src/components/link/index.test.tsx +199 -199
- package/src/components/link/index.tsx +116 -116
- package/src/components/link/types.ts +25 -25
- package/src/components/list/List.stories.tsx +272 -272
- package/src/components/list/index.test.tsx +166 -166
- package/src/components/list/index.tsx +88 -88
- package/src/components/list/list-item/index.tsx +38 -38
- package/src/components/list/list-item/types.ts +13 -13
- package/src/components/list/types.ts +29 -29
- package/src/components/material-icon/MaterialIcon.stories.tsx +322 -322
- package/src/components/material-icon/constants.ts +99 -99
- package/src/components/material-icon/index.test.tsx +130 -130
- package/src/components/material-icon/index.tsx +47 -47
- package/src/components/material-icon/types.ts +31 -31
- package/src/components/modal/Modal.stories.tsx +171 -171
- package/src/components/modal/index.test.tsx +310 -310
- package/src/components/modal/index.tsx +164 -164
- package/src/components/modal/types.ts +24 -24
- package/src/components/next-image/index.test.tsx +406 -406
- package/src/components/next-image/index.tsx +74 -74
- package/src/components/next-image/types.ts +1 -1
- package/src/components/pagination/index.test.tsx +521 -521
- package/src/components/pagination/index.tsx +91 -91
- package/src/components/pagination/types.ts +6 -6
- package/src/components/radio-button/RadioButton.stories.tsx +307 -307
- package/src/components/radio-button/index.test.tsx +151 -151
- package/src/components/radio-button/index.tsx +75 -75
- package/src/components/radio-button/types.ts +21 -21
- package/src/components/see-more/SeeMore.stories.tsx +181 -181
- package/src/components/see-more/index.test.tsx +96 -96
- package/src/components/see-more/index.tsx +44 -44
- package/src/components/see-more/types.ts +4 -4
- package/src/components/select/Select.stories.tsx +411 -411
- package/src/components/select/index.test.tsx +256 -256
- package/src/components/select/index.tsx +155 -155
- package/src/components/select/types.ts +36 -36
- package/src/components/select-plan-button/SelectPlanButton.stories.tsx +184 -184
- package/src/components/select-plan-button/index.test.tsx +173 -173
- package/src/components/select-plan-button/index.tsx +63 -63
- package/src/components/select-plan-button/types.ts +17 -17
- package/src/components/skeleton/Skeleton.stories.tsx +179 -179
- package/src/components/skeleton/index.test.tsx +74 -74
- package/src/components/skeleton/index.tsx +61 -61
- package/src/components/skeleton/types.ts +4 -4
- package/src/components/spinner/Spinner.stories.tsx +335 -335
- package/src/components/spinner/index.test.tsx +76 -76
- package/src/components/spinner/index.tsx +44 -44
- package/src/components/spinner/types.ts +5 -5
- package/src/components/text/Text.stories.tsx +321 -321
- package/src/components/text/index.test.tsx +65 -65
- package/src/components/text/index.tsx +25 -25
- package/src/components/text/types.ts +45 -45
- package/src/components/tooltip/Tooltip.stories.tsx +219 -219
- package/src/components/tooltip/index.test.tsx +50 -50
- package/src/components/tooltip/index.tsx +74 -74
- package/src/components/tooltip/types.ts +7 -7
- package/src/components/view-cart-button/ViewCartButton.stories.tsx +252 -252
- package/src/components/view-cart-button/index.test.tsx +57 -57
- package/src/components/view-cart-button/index.tsx +42 -42
- package/src/components/view-cart-button/types.ts +5 -5
- package/src/contentful/blocks/accordion/Accordion.stories.mocks.tsx +128 -128
- package/src/contentful/blocks/accordion/Accordion.stories.tsx +98 -98
- package/src/contentful/blocks/accordion/index.test.tsx +218 -218
- package/src/contentful/blocks/accordion/index.tsx +114 -114
- package/src/contentful/blocks/accordion/types.ts +34 -34
- package/src/contentful/blocks/address-input-banner/index.test.tsx +132 -132
- package/src/contentful/blocks/address-input-banner/index.tsx +52 -52
- package/src/contentful/blocks/address-input-banner/types.ts +14 -14
- package/src/contentful/blocks/anchored-bottom-banner/index.test.tsx +287 -287
- package/src/contentful/blocks/anchored-bottom-banner/index.tsx +181 -181
- package/src/contentful/blocks/anchored-bottom-banner/types.ts +13 -13
- package/src/contentful/blocks/blogs-grid/BlogGrid.stories.mocks.tsx +144 -144
- package/src/contentful/blocks/blogs-grid/BlogGrid.stories.tsx +157 -157
- package/src/contentful/blocks/blogs-grid/index.test.tsx +355 -355
- package/src/contentful/blocks/blogs-grid/index.tsx +134 -134
- package/src/contentful/blocks/blogs-grid/types.ts +26 -26
- package/src/contentful/blocks/blogs-grid-base/index.test.tsx +274 -274
- package/src/contentful/blocks/blogs-grid-base/index.tsx +119 -119
- package/src/contentful/blocks/blogs-grid-base/types.ts +36 -36
- package/src/contentful/blocks/breadcrumbs/BreadcrumbNavigation.stories.tsx +147 -147
- package/src/contentful/blocks/breadcrumbs/index.test.tsx +281 -281
- package/src/contentful/blocks/breadcrumbs/index.tsx +95 -95
- package/src/contentful/blocks/breadcrumbs/types.ts +8 -8
- package/src/contentful/blocks/button/Button.stories.tsx +40 -40
- package/src/contentful/blocks/button/index.test.tsx +339 -339
- package/src/contentful/blocks/button/index.tsx +131 -131
- package/src/contentful/blocks/button/types.ts +39 -39
- package/src/contentful/blocks/callout/Callout.stories.tsx +23 -23
- package/src/contentful/blocks/callout/index.test.tsx +539 -539
- package/src/contentful/blocks/callout/index.tsx +277 -277
- package/src/contentful/blocks/callout/types.ts +78 -78
- package/src/contentful/blocks/cards/Cards.stories.tsx +23 -23
- package/src/contentful/blocks/cards/blog-card/index.test.tsx +218 -218
- package/src/contentful/blocks/cards/blog-card/index.tsx +129 -129
- package/src/contentful/blocks/cards/blog-card/types.ts +34 -34
- package/src/contentful/blocks/cards/floating-image-card/index.test.tsx +201 -201
- package/src/contentful/blocks/cards/floating-image-card/index.tsx +119 -119
- package/src/contentful/blocks/cards/floating-image-card/types.ts +30 -30
- package/src/contentful/blocks/cards/full-image-card/index.test.tsx +216 -216
- package/src/contentful/blocks/cards/full-image-card/index.tsx +130 -130
- package/src/contentful/blocks/cards/full-image-card/types.ts +29 -29
- package/src/contentful/blocks/cards/index.test.tsx +39 -39
- package/src/contentful/blocks/cards/index.tsx +13 -13
- package/src/contentful/blocks/cards/product-card/index.test.tsx +263 -263
- package/src/contentful/blocks/cards/product-card/index.tsx +251 -251
- package/src/contentful/blocks/cards/product-card/types.ts +28 -28
- package/src/contentful/blocks/cards/simple-card/index.test.tsx +364 -364
- package/src/contentful/blocks/cards/simple-card/index.tsx +325 -325
- package/src/contentful/blocks/cards/simple-card/types.ts +71 -71
- package/src/contentful/blocks/cards/testimonial-card/index.test.tsx +180 -180
- package/src/contentful/blocks/cards/testimonial-card/index.tsx +90 -90
- package/src/contentful/blocks/cards/testimonial-card/types.tsx +12 -12
- package/src/contentful/blocks/cards/types.ts +1 -1
- package/src/contentful/blocks/carousel/Carousel.stories.tsx +23 -23
- package/src/contentful/blocks/carousel/helper.test.tsx +539 -539
- package/src/contentful/blocks/carousel/helper.tsx +494 -494
- package/src/contentful/blocks/carousel/index.test.tsx +308 -308
- package/src/contentful/blocks/carousel/index.tsx +87 -87
- package/src/contentful/blocks/carousel/types.test.ts +16 -16
- package/src/contentful/blocks/carousel/types.ts +145 -145
- package/src/contentful/blocks/cart-retention-banner/index.test.tsx +409 -409
- package/src/contentful/blocks/cart-retention-banner/index.tsx +109 -109
- package/src/contentful/blocks/cart-retention-banner/types.ts +11 -11
- package/src/contentful/blocks/comparison-table/index.test.tsx +114 -114
- package/src/contentful/blocks/comparison-table/index.tsx +29 -29
- package/src/contentful/blocks/comparison-table/types.ts +6 -6
- package/src/contentful/blocks/cookiebanner/index.test.tsx +277 -277
- package/src/contentful/blocks/cookiebanner/index.tsx +146 -146
- package/src/contentful/blocks/cookiebanner/type.ts +7 -7
- package/src/contentful/blocks/cta-callout/CtaCallout.stories.tsx +46 -46
- package/src/contentful/blocks/cta-callout/index.test.tsx +244 -244
- package/src/contentful/blocks/cta-callout/index.tsx +73 -73
- package/src/contentful/blocks/cta-callout/types.ts +26 -26
- package/src/contentful/blocks/dynamic-tabs/index.test.tsx +240 -240
- package/src/contentful/blocks/dynamic-tabs/index.tsx +204 -204
- package/src/contentful/blocks/dynamic-tabs/types.ts +21 -21
- package/src/contentful/blocks/email-input-block/index.test.tsx +213 -213
- package/src/contentful/blocks/email-input-block/index.tsx +121 -121
- package/src/contentful/blocks/email-input-block/types.ts +16 -16
- package/src/contentful/blocks/find-kinetic/FindKinetic.stories.tsx +23 -23
- package/src/contentful/blocks/find-kinetic/index.test.tsx +269 -269
- package/src/contentful/blocks/find-kinetic/index.tsx +138 -138
- package/src/contentful/blocks/find-kinetic/types.ts +20 -20
- package/src/contentful/blocks/floating-banner/FloatingBanner.stories.tsx +34 -34
- package/src/contentful/blocks/floating-banner/index.test.tsx +246 -246
- package/src/contentful/blocks/floating-banner/index.tsx +97 -97
- package/src/contentful/blocks/floating-banner/types.ts +22 -22
- package/src/contentful/blocks/footer/Footer.stories.tsx +317 -317
- package/src/contentful/blocks/footer/index.test.tsx +302 -302
- package/src/contentful/blocks/footer/index.tsx +91 -91
- package/src/contentful/blocks/footer/types.ts +13 -13
- package/src/contentful/blocks/image-promo-bar/ImagePromoBar.stories.tsx +23 -23
- package/src/contentful/blocks/image-promo-bar/helper.test.tsx +61 -61
- package/src/contentful/blocks/image-promo-bar/helper.tsx +28 -28
- package/src/contentful/blocks/image-promo-bar/index.test.tsx +467 -467
- package/src/contentful/blocks/image-promo-bar/index.tsx +8 -6
- package/src/contentful/blocks/image-promo-bar/types.ts +44 -44
- package/src/contentful/blocks/image-promo-bar/vimeo-embed.test.tsx +142 -142
- package/src/contentful/blocks/image-promo-bar/vimeo-embed.tsx +93 -93
- package/src/contentful/blocks/image-promo-bar/youtube-embed.test.tsx +104 -104
- package/src/contentful/blocks/image-promo-bar/youtube-embed.tsx +46 -46
- package/src/contentful/blocks/modal/constants.ts +53 -53
- package/src/contentful/blocks/modal/index.test.tsx +209 -209
- package/src/contentful/blocks/modal/index.tsx +108 -108
- package/src/contentful/blocks/modal/types.ts +12 -12
- package/src/contentful/blocks/navigation/Navigation.stories.mocks.tsx +78 -78
- package/src/contentful/blocks/navigation/Navigation.stories.tsx +138 -138
- package/src/contentful/blocks/navigation/desktop-link-groups.tsx/index.test.tsx +208 -208
- package/src/contentful/blocks/navigation/desktop-link-groups.tsx/index.tsx +141 -141
- package/src/contentful/blocks/navigation/index.test.tsx +924 -924
- package/src/contentful/blocks/navigation/index.tsx +569 -569
- package/src/contentful/blocks/navigation/mobile-link-groups.tsx/index.test.tsx +131 -131
- package/src/contentful/blocks/navigation/mobile-link-groups.tsx/index.tsx +82 -82
- package/src/contentful/blocks/navigation/types.ts +71 -71
- package/src/contentful/blocks/primary-hero/PrimaryHero.stories.tsx +23 -23
- package/src/contentful/blocks/primary-hero/index.test.tsx +286 -286
- package/src/contentful/blocks/primary-hero/index.tsx +239 -239
- package/src/contentful/blocks/primary-hero/types.ts +37 -37
- package/src/contentful/blocks/search-block/index.test.tsx +268 -268
- package/src/contentful/blocks/search-block/index.tsx +90 -90
- package/src/contentful/blocks/search-block/types.ts +15 -15
- package/src/contentful/blocks/shape-background-wrapper/ShapeBackgroundWrapper.stories.tsx +26 -26
- package/src/contentful/blocks/shape-background-wrapper/index.test.tsx +284 -284
- package/src/contentful/blocks/shape-background-wrapper/index.tsx +124 -124
- package/src/contentful/blocks/shape-background-wrapper/types.ts +36 -36
- package/src/contentful/blocks/text/Text.stories.tsx +23 -23
- package/src/contentful/blocks/text/index.test.tsx +36 -36
- package/src/contentful/blocks/text/index.tsx +12 -12
- package/src/contentful/blocks/text/types.ts +1 -1
- package/src/contentful/index.test.ts +45 -45
- package/src/contentful/index.ts +105 -105
- package/src/global-mocks/contentful/to-document.ts +25 -25
- package/src/global-mocks/cookie.ts +48 -48
- package/src/global-mocks/cx.ts +37 -37
- package/src/global-mocks/index.ts +89 -89
- package/src/global-mocks/speed-card-bg.ts +27 -27
- package/src/global-mocks/utm.ts +49 -49
- package/src/hooks/contentful/use-contentful-rich-text.test.tsx +1758 -1758
- package/src/hooks/contentful/use-contentful-rich-text.tsx +309 -309
- package/src/hooks/contentful/use-processed-check-list.test.tsx +277 -277
- package/src/hooks/contentful/use-processed-check-list.ts +63 -63
- package/src/hooks/use-body-scroll-lock.test.ts +134 -134
- package/src/hooks/use-body-scroll-lock.ts +34 -34
- package/src/hooks/use-carousel-swipe.test.ts +393 -393
- package/src/hooks/use-carousel-swipe.ts +264 -264
- package/src/hooks/use-outside-click.test.ts +142 -142
- package/src/hooks/use-outside-click.ts +17 -17
- package/src/index.ts +107 -107
- package/src/next/index.test.ts +7 -7
- package/src/next/index.ts +5 -5
- package/src/setupTests.ts +52 -52
- package/src/stories/DocsTemplate.tsx +24 -24
- package/src/styles/globals.css +343 -343
- package/src/types/global.d.ts +9 -9
- package/src/types/micro-components.ts +99 -99
- package/src/types/utm.ts +49 -49
- package/src/utils/contentful/to-document.test.ts +85 -85
- package/src/utils/contentful/to-document.ts +24 -24
- package/src/utils/cookie.test.ts +180 -180
- package/src/utils/cookie.ts +84 -84
- package/src/utils/cx.test.ts +90 -90
- package/src/utils/cx.ts +49 -49
- package/src/utils/index.test.ts +115 -115
- package/src/utils/index.ts +41 -41
- package/src/utils/speed-card-bg.test.ts +46 -46
- package/src/utils/speed-card-bg.ts +24 -24
- package/src/utils/utm.test.ts +359 -359
- package/src/utils/utm.ts +221 -221
package/src/utils/cookie.test.ts
CHANGED
|
@@ -1,180 +1,180 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getCookie,
|
|
3
|
-
getParsedCookie,
|
|
4
|
-
getUTMs,
|
|
5
|
-
removeUTMs,
|
|
6
|
-
setCookie,
|
|
7
|
-
setUTMs,
|
|
8
|
-
} from "./cookie";
|
|
9
|
-
import { Base64 } from "js-base64";
|
|
10
|
-
import Cookies from "js-cookie";
|
|
11
|
-
|
|
12
|
-
jest.mock("js-cookie");
|
|
13
|
-
|
|
14
|
-
const mockCookiesGet = Cookies.get as jest.Mock;
|
|
15
|
-
const mockCookiesSet = Cookies.set as jest.Mock;
|
|
16
|
-
const mockCookiesRemove = Cookies.remove as jest.Mock;
|
|
17
|
-
|
|
18
|
-
describe("cookie utilities", () => {
|
|
19
|
-
afterEach(() => {
|
|
20
|
-
mockCookiesGet.mockReset();
|
|
21
|
-
mockCookiesSet.mockReset();
|
|
22
|
-
mockCookiesRemove.mockReset();
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
// ── getUTMs ──────────────────────────────────────────
|
|
26
|
-
describe("getUTMs", () => {
|
|
27
|
-
it("returns null when window is undefined", () => {
|
|
28
|
-
const origWindow = globalThis.window;
|
|
29
|
-
// @ts-expect-error - intentionally deleting window
|
|
30
|
-
delete globalThis.window;
|
|
31
|
-
expect(getUTMs()).toBeNull();
|
|
32
|
-
globalThis.window = origWindow;
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("returns null when cookie does not exist", () => {
|
|
36
|
-
mockCookiesGet.mockReturnValue(undefined as any);
|
|
37
|
-
expect(getUTMs()).toBeNull();
|
|
38
|
-
expect(mockCookiesGet).toHaveBeenCalledWith("utm_parameters");
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("decodes and parses a valid Base64 cookie", () => {
|
|
42
|
-
const utms = { utm_source: "google", utm_medium: "cpc" };
|
|
43
|
-
const encoded = Base64.encode(JSON.stringify(utms));
|
|
44
|
-
mockCookiesGet.mockReturnValue(encoded as any);
|
|
45
|
-
|
|
46
|
-
expect(getUTMs()).toEqual(utms);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it("returns null for an invalid Base64/JSON cookie", () => {
|
|
50
|
-
mockCookiesGet.mockReturnValue("not-valid-base64!!!" as any);
|
|
51
|
-
expect(getUTMs()).toBeNull();
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
// ── setUTMs ──────────────────────────────────────────
|
|
56
|
-
describe("setUTMs", () => {
|
|
57
|
-
it("returns early when window is undefined", () => {
|
|
58
|
-
const origWindow = globalThis.window;
|
|
59
|
-
// @ts-expect-error - intentionally deleting window
|
|
60
|
-
delete globalThis.window;
|
|
61
|
-
setUTMs({ utm_source: "test" });
|
|
62
|
-
expect(mockCookiesSet).not.toHaveBeenCalled();
|
|
63
|
-
globalThis.window = origWindow;
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it("encodes UTMs to Base64 and sets cookie with default domain", () => {
|
|
67
|
-
const utms = { utm_source: "google" };
|
|
68
|
-
setUTMs(utms);
|
|
69
|
-
|
|
70
|
-
const expectedEncoded = Base64.encode(JSON.stringify(utms));
|
|
71
|
-
expect(mockCookiesSet).toHaveBeenCalledWith(
|
|
72
|
-
"utm_parameters",
|
|
73
|
-
expectedEncoded,
|
|
74
|
-
{ domain: ".gokinetic.com", path: "/", sameSite: "Lax" }
|
|
75
|
-
);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it("accepts a custom domain", () => {
|
|
79
|
-
setUTMs({ utm_source: "bing" }, ".custom.com");
|
|
80
|
-
expect(mockCookiesSet).toHaveBeenCalledWith(
|
|
81
|
-
"utm_parameters",
|
|
82
|
-
expect.any(String),
|
|
83
|
-
{ domain: ".custom.com", path: "/", sameSite: "Lax" }
|
|
84
|
-
);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// ── removeUTMs ───────────────────────────────────────
|
|
89
|
-
describe("removeUTMs", () => {
|
|
90
|
-
it("removes cookie with default domain", () => {
|
|
91
|
-
removeUTMs();
|
|
92
|
-
expect(mockCookiesRemove).toHaveBeenCalledWith("utm_parameters", {
|
|
93
|
-
domain: ".gokinetic.com",
|
|
94
|
-
path: "/",
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it("removes cookie with custom domain", () => {
|
|
99
|
-
removeUTMs(".other.com");
|
|
100
|
-
expect(mockCookiesRemove).toHaveBeenCalledWith("utm_parameters", {
|
|
101
|
-
domain: ".other.com",
|
|
102
|
-
path: "/",
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// ── getCookie ────────────────────────────────────────
|
|
108
|
-
describe("getCookie", () => {
|
|
109
|
-
it("returns empty string when window is undefined", () => {
|
|
110
|
-
const origWindow = globalThis.window;
|
|
111
|
-
// @ts-expect-error - intentionally deleting window
|
|
112
|
-
delete globalThis.window;
|
|
113
|
-
expect(getCookie("key")).toBe("");
|
|
114
|
-
globalThis.window = origWindow;
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it("returns decoded value when cookie exists", () => {
|
|
118
|
-
const value = "hello world";
|
|
119
|
-
mockCookiesGet.mockReturnValue(Base64.encode(value) as any);
|
|
120
|
-
expect(getCookie("my_key")).toBe(value);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it("returns null when cookie does not exist", () => {
|
|
124
|
-
mockCookiesGet.mockReturnValue(undefined as any);
|
|
125
|
-
expect(getCookie("missing")).toBeNull();
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
// ── getParsedCookie ──────────────────────────────────
|
|
130
|
-
describe("getParsedCookie", () => {
|
|
131
|
-
it("returns parsed JSON from cookie", () => {
|
|
132
|
-
const obj = { foo: "bar", num: 42 };
|
|
133
|
-
mockCookiesGet.mockReturnValue(Base64.encode(JSON.stringify(obj)) as any);
|
|
134
|
-
expect(getParsedCookie("key")).toEqual(obj);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it("returns null when cookie is missing", () => {
|
|
138
|
-
mockCookiesGet.mockReturnValue(undefined as any);
|
|
139
|
-
expect(getParsedCookie("missing")).toBeNull();
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it("returns null when cookie has invalid JSON", () => {
|
|
143
|
-
mockCookiesGet.mockReturnValue(Base64.encode("not json") as any);
|
|
144
|
-
expect(getParsedCookie("bad")).toBeNull();
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
// ── setCookie ────────────────────────────────────────
|
|
149
|
-
describe("setCookie", () => {
|
|
150
|
-
it("returns early when window is undefined", () => {
|
|
151
|
-
const origWindow = globalThis.window;
|
|
152
|
-
// @ts-expect-error - intentionally deleting window
|
|
153
|
-
delete globalThis.window;
|
|
154
|
-
setCookie("key", "value", {});
|
|
155
|
-
expect(mockCookiesSet).not.toHaveBeenCalled();
|
|
156
|
-
globalThis.window = origWindow;
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it("encodes value to Base64 and sets cookie with options", () => {
|
|
160
|
-
const value = { plan: "fiber", speed: 500 };
|
|
161
|
-
const options = { domain: ".test.com", path: "/" };
|
|
162
|
-
setCookie("plan_data", value, options);
|
|
163
|
-
|
|
164
|
-
const expectedEncoded = Base64.encode(JSON.stringify(value));
|
|
165
|
-
expect(mockCookiesSet).toHaveBeenCalledWith(
|
|
166
|
-
"plan_data",
|
|
167
|
-
expectedEncoded,
|
|
168
|
-
options
|
|
169
|
-
);
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
it("handles string values", () => {
|
|
173
|
-
setCookie("simple", "hello", { path: "/" });
|
|
174
|
-
const expectedEncoded = Base64.encode(JSON.stringify("hello"));
|
|
175
|
-
expect(mockCookiesSet).toHaveBeenCalledWith("simple", expectedEncoded, {
|
|
176
|
-
path: "/",
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
});
|
|
1
|
+
import {
|
|
2
|
+
getCookie,
|
|
3
|
+
getParsedCookie,
|
|
4
|
+
getUTMs,
|
|
5
|
+
removeUTMs,
|
|
6
|
+
setCookie,
|
|
7
|
+
setUTMs,
|
|
8
|
+
} from "./cookie";
|
|
9
|
+
import { Base64 } from "js-base64";
|
|
10
|
+
import Cookies from "js-cookie";
|
|
11
|
+
|
|
12
|
+
jest.mock("js-cookie");
|
|
13
|
+
|
|
14
|
+
const mockCookiesGet = Cookies.get as jest.Mock;
|
|
15
|
+
const mockCookiesSet = Cookies.set as jest.Mock;
|
|
16
|
+
const mockCookiesRemove = Cookies.remove as jest.Mock;
|
|
17
|
+
|
|
18
|
+
describe("cookie utilities", () => {
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
mockCookiesGet.mockReset();
|
|
21
|
+
mockCookiesSet.mockReset();
|
|
22
|
+
mockCookiesRemove.mockReset();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// ── getUTMs ──────────────────────────────────────────
|
|
26
|
+
describe("getUTMs", () => {
|
|
27
|
+
it("returns null when window is undefined", () => {
|
|
28
|
+
const origWindow = globalThis.window;
|
|
29
|
+
// @ts-expect-error - intentionally deleting window
|
|
30
|
+
delete globalThis.window;
|
|
31
|
+
expect(getUTMs()).toBeNull();
|
|
32
|
+
globalThis.window = origWindow;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("returns null when cookie does not exist", () => {
|
|
36
|
+
mockCookiesGet.mockReturnValue(undefined as any);
|
|
37
|
+
expect(getUTMs()).toBeNull();
|
|
38
|
+
expect(mockCookiesGet).toHaveBeenCalledWith("utm_parameters");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("decodes and parses a valid Base64 cookie", () => {
|
|
42
|
+
const utms = { utm_source: "google", utm_medium: "cpc" };
|
|
43
|
+
const encoded = Base64.encode(JSON.stringify(utms));
|
|
44
|
+
mockCookiesGet.mockReturnValue(encoded as any);
|
|
45
|
+
|
|
46
|
+
expect(getUTMs()).toEqual(utms);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("returns null for an invalid Base64/JSON cookie", () => {
|
|
50
|
+
mockCookiesGet.mockReturnValue("not-valid-base64!!!" as any);
|
|
51
|
+
expect(getUTMs()).toBeNull();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// ── setUTMs ──────────────────────────────────────────
|
|
56
|
+
describe("setUTMs", () => {
|
|
57
|
+
it("returns early when window is undefined", () => {
|
|
58
|
+
const origWindow = globalThis.window;
|
|
59
|
+
// @ts-expect-error - intentionally deleting window
|
|
60
|
+
delete globalThis.window;
|
|
61
|
+
setUTMs({ utm_source: "test" });
|
|
62
|
+
expect(mockCookiesSet).not.toHaveBeenCalled();
|
|
63
|
+
globalThis.window = origWindow;
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("encodes UTMs to Base64 and sets cookie with default domain", () => {
|
|
67
|
+
const utms = { utm_source: "google" };
|
|
68
|
+
setUTMs(utms);
|
|
69
|
+
|
|
70
|
+
const expectedEncoded = Base64.encode(JSON.stringify(utms));
|
|
71
|
+
expect(mockCookiesSet).toHaveBeenCalledWith(
|
|
72
|
+
"utm_parameters",
|
|
73
|
+
expectedEncoded,
|
|
74
|
+
{ domain: ".gokinetic.com", path: "/", sameSite: "Lax" }
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("accepts a custom domain", () => {
|
|
79
|
+
setUTMs({ utm_source: "bing" }, ".custom.com");
|
|
80
|
+
expect(mockCookiesSet).toHaveBeenCalledWith(
|
|
81
|
+
"utm_parameters",
|
|
82
|
+
expect.any(String),
|
|
83
|
+
{ domain: ".custom.com", path: "/", sameSite: "Lax" }
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// ── removeUTMs ───────────────────────────────────────
|
|
89
|
+
describe("removeUTMs", () => {
|
|
90
|
+
it("removes cookie with default domain", () => {
|
|
91
|
+
removeUTMs();
|
|
92
|
+
expect(mockCookiesRemove).toHaveBeenCalledWith("utm_parameters", {
|
|
93
|
+
domain: ".gokinetic.com",
|
|
94
|
+
path: "/",
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("removes cookie with custom domain", () => {
|
|
99
|
+
removeUTMs(".other.com");
|
|
100
|
+
expect(mockCookiesRemove).toHaveBeenCalledWith("utm_parameters", {
|
|
101
|
+
domain: ".other.com",
|
|
102
|
+
path: "/",
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// ── getCookie ────────────────────────────────────────
|
|
108
|
+
describe("getCookie", () => {
|
|
109
|
+
it("returns empty string when window is undefined", () => {
|
|
110
|
+
const origWindow = globalThis.window;
|
|
111
|
+
// @ts-expect-error - intentionally deleting window
|
|
112
|
+
delete globalThis.window;
|
|
113
|
+
expect(getCookie("key")).toBe("");
|
|
114
|
+
globalThis.window = origWindow;
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("returns decoded value when cookie exists", () => {
|
|
118
|
+
const value = "hello world";
|
|
119
|
+
mockCookiesGet.mockReturnValue(Base64.encode(value) as any);
|
|
120
|
+
expect(getCookie("my_key")).toBe(value);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("returns null when cookie does not exist", () => {
|
|
124
|
+
mockCookiesGet.mockReturnValue(undefined as any);
|
|
125
|
+
expect(getCookie("missing")).toBeNull();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// ── getParsedCookie ──────────────────────────────────
|
|
130
|
+
describe("getParsedCookie", () => {
|
|
131
|
+
it("returns parsed JSON from cookie", () => {
|
|
132
|
+
const obj = { foo: "bar", num: 42 };
|
|
133
|
+
mockCookiesGet.mockReturnValue(Base64.encode(JSON.stringify(obj)) as any);
|
|
134
|
+
expect(getParsedCookie("key")).toEqual(obj);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("returns null when cookie is missing", () => {
|
|
138
|
+
mockCookiesGet.mockReturnValue(undefined as any);
|
|
139
|
+
expect(getParsedCookie("missing")).toBeNull();
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("returns null when cookie has invalid JSON", () => {
|
|
143
|
+
mockCookiesGet.mockReturnValue(Base64.encode("not json") as any);
|
|
144
|
+
expect(getParsedCookie("bad")).toBeNull();
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// ── setCookie ────────────────────────────────────────
|
|
149
|
+
describe("setCookie", () => {
|
|
150
|
+
it("returns early when window is undefined", () => {
|
|
151
|
+
const origWindow = globalThis.window;
|
|
152
|
+
// @ts-expect-error - intentionally deleting window
|
|
153
|
+
delete globalThis.window;
|
|
154
|
+
setCookie("key", "value", {});
|
|
155
|
+
expect(mockCookiesSet).not.toHaveBeenCalled();
|
|
156
|
+
globalThis.window = origWindow;
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("encodes value to Base64 and sets cookie with options", () => {
|
|
160
|
+
const value = { plan: "fiber", speed: 500 };
|
|
161
|
+
const options = { domain: ".test.com", path: "/" };
|
|
162
|
+
setCookie("plan_data", value, options);
|
|
163
|
+
|
|
164
|
+
const expectedEncoded = Base64.encode(JSON.stringify(value));
|
|
165
|
+
expect(mockCookiesSet).toHaveBeenCalledWith(
|
|
166
|
+
"plan_data",
|
|
167
|
+
expectedEncoded,
|
|
168
|
+
options
|
|
169
|
+
);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("handles string values", () => {
|
|
173
|
+
setCookie("simple", "hello", { path: "/" });
|
|
174
|
+
const expectedEncoded = Base64.encode(JSON.stringify("hello"));
|
|
175
|
+
expect(mockCookiesSet).toHaveBeenCalledWith("simple", expectedEncoded, {
|
|
176
|
+
path: "/",
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
});
|
package/src/utils/cookie.ts
CHANGED
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cookie Helpers for UTM Parameter Storage
|
|
3
|
-
*
|
|
4
|
-
* Provides Base64-encoded JSON cookie storage for UTM parameters.
|
|
5
|
-
*/
|
|
6
|
-
import type { UTMProperties } from "../types/utm";
|
|
7
|
-
import { Base64 } from "js-base64";
|
|
8
|
-
import Cookies from "js-cookie";
|
|
9
|
-
|
|
10
|
-
const UTM_COOKIE_KEY = "utm_parameters";
|
|
11
|
-
const DEFAULT_DOMAIN = ".gokinetic.com";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Reads UTM parameters from the Base64-encoded cookie.
|
|
15
|
-
* @returns Parsed UTMProperties or null if cookie doesn't exist / is invalid.
|
|
16
|
-
*/
|
|
17
|
-
export function getUTMs(): UTMProperties | null {
|
|
18
|
-
if (typeof window === "undefined") return null;
|
|
19
|
-
|
|
20
|
-
const raw = Cookies.get(UTM_COOKIE_KEY);
|
|
21
|
-
if (!raw) return null;
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
const decoded = Base64.decode(raw);
|
|
25
|
-
return JSON.parse(decoded) as UTMProperties;
|
|
26
|
-
} catch {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Stores UTM parameters as a Base64-encoded JSON cookie.
|
|
33
|
-
* @param utms - The UTM properties to store.
|
|
34
|
-
* @param domain - Cookie domain (defaults to `.gokinetic.com`).
|
|
35
|
-
*/
|
|
36
|
-
export function setUTMs(
|
|
37
|
-
utms: UTMProperties,
|
|
38
|
-
domain: string = DEFAULT_DOMAIN
|
|
39
|
-
): void {
|
|
40
|
-
if (typeof window === "undefined") return;
|
|
41
|
-
|
|
42
|
-
const json = JSON.stringify(utms);
|
|
43
|
-
const encoded = Base64.encode(json);
|
|
44
|
-
|
|
45
|
-
Cookies.set(UTM_COOKIE_KEY, encoded, {
|
|
46
|
-
domain,
|
|
47
|
-
path: "/",
|
|
48
|
-
sameSite: "Lax",
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Removes the UTM cookie.
|
|
54
|
-
* @param domain - Cookie domain (defaults to `.gokinetic.com`).
|
|
55
|
-
*/
|
|
56
|
-
export function removeUTMs(domain: string = DEFAULT_DOMAIN): void {
|
|
57
|
-
Cookies.remove(UTM_COOKIE_KEY, { domain, path: "/" });
|
|
58
|
-
}
|
|
59
|
-
export function getCookie(key: string): string | null {
|
|
60
|
-
if (typeof window === "undefined") return "";
|
|
61
|
-
const encryptedValue = Cookies.get(key);
|
|
62
|
-
|
|
63
|
-
if (encryptedValue) return Base64.decode(encryptedValue);
|
|
64
|
-
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
export const getParsedCookie = (key: string) => {
|
|
68
|
-
try {
|
|
69
|
-
return JSON.parse(getCookie(key) || "");
|
|
70
|
-
} catch {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
export const setCookie = (
|
|
75
|
-
key: string,
|
|
76
|
-
value: any,
|
|
77
|
-
options: Cookies.CookieAttributes
|
|
78
|
-
) => {
|
|
79
|
-
if (typeof window === "undefined") return;
|
|
80
|
-
const stringValue = JSON.stringify(value);
|
|
81
|
-
const encryptedValue = Base64.encode(stringValue);
|
|
82
|
-
|
|
83
|
-
Cookies.set(key, encryptedValue, options);
|
|
84
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Cookie Helpers for UTM Parameter Storage
|
|
3
|
+
*
|
|
4
|
+
* Provides Base64-encoded JSON cookie storage for UTM parameters.
|
|
5
|
+
*/
|
|
6
|
+
import type { UTMProperties } from "../types/utm";
|
|
7
|
+
import { Base64 } from "js-base64";
|
|
8
|
+
import Cookies from "js-cookie";
|
|
9
|
+
|
|
10
|
+
const UTM_COOKIE_KEY = "utm_parameters";
|
|
11
|
+
const DEFAULT_DOMAIN = ".gokinetic.com";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Reads UTM parameters from the Base64-encoded cookie.
|
|
15
|
+
* @returns Parsed UTMProperties or null if cookie doesn't exist / is invalid.
|
|
16
|
+
*/
|
|
17
|
+
export function getUTMs(): UTMProperties | null {
|
|
18
|
+
if (typeof window === "undefined") return null;
|
|
19
|
+
|
|
20
|
+
const raw = Cookies.get(UTM_COOKIE_KEY);
|
|
21
|
+
if (!raw) return null;
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const decoded = Base64.decode(raw);
|
|
25
|
+
return JSON.parse(decoded) as UTMProperties;
|
|
26
|
+
} catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Stores UTM parameters as a Base64-encoded JSON cookie.
|
|
33
|
+
* @param utms - The UTM properties to store.
|
|
34
|
+
* @param domain - Cookie domain (defaults to `.gokinetic.com`).
|
|
35
|
+
*/
|
|
36
|
+
export function setUTMs(
|
|
37
|
+
utms: UTMProperties,
|
|
38
|
+
domain: string = DEFAULT_DOMAIN
|
|
39
|
+
): void {
|
|
40
|
+
if (typeof window === "undefined") return;
|
|
41
|
+
|
|
42
|
+
const json = JSON.stringify(utms);
|
|
43
|
+
const encoded = Base64.encode(json);
|
|
44
|
+
|
|
45
|
+
Cookies.set(UTM_COOKIE_KEY, encoded, {
|
|
46
|
+
domain,
|
|
47
|
+
path: "/",
|
|
48
|
+
sameSite: "Lax",
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Removes the UTM cookie.
|
|
54
|
+
* @param domain - Cookie domain (defaults to `.gokinetic.com`).
|
|
55
|
+
*/
|
|
56
|
+
export function removeUTMs(domain: string = DEFAULT_DOMAIN): void {
|
|
57
|
+
Cookies.remove(UTM_COOKIE_KEY, { domain, path: "/" });
|
|
58
|
+
}
|
|
59
|
+
export function getCookie(key: string): string | null {
|
|
60
|
+
if (typeof window === "undefined") return "";
|
|
61
|
+
const encryptedValue = Cookies.get(key);
|
|
62
|
+
|
|
63
|
+
if (encryptedValue) return Base64.decode(encryptedValue);
|
|
64
|
+
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
export const getParsedCookie = (key: string) => {
|
|
68
|
+
try {
|
|
69
|
+
return JSON.parse(getCookie(key) || "");
|
|
70
|
+
} catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
export const setCookie = (
|
|
75
|
+
key: string,
|
|
76
|
+
value: any,
|
|
77
|
+
options: Cookies.CookieAttributes
|
|
78
|
+
) => {
|
|
79
|
+
if (typeof window === "undefined") return;
|
|
80
|
+
const stringValue = JSON.stringify(value);
|
|
81
|
+
const encryptedValue = Base64.encode(stringValue);
|
|
82
|
+
|
|
83
|
+
Cookies.set(key, encryptedValue, options);
|
|
84
|
+
};
|