Skip to content
This repository was archived by the owner on Mar 3, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions packages/react/src/ShopifyCookies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ interface ShopifyCookiesProps {
hasUserConsent?: boolean;
}

/**
* Set user and session cookies and refresh the expiry time
* @param domain - The domain scope of the cookie
* @param hasUserConsent - Defaults to false. If hasUserConsent is true, we can set Shopify unique user token cookie
* @example
* ```tsx
* import {ShopifyCookies} from '@shopify/hydrogen-react';
*
* <ShopifyCookies domain="" hasUserConsent={hasUserConsent} />
* ```
*/
export function ShopifyCookies(props: ShopifyCookiesProps) {
const {domain = '', hasUserConsent = false} = props;

Expand Down
29 changes: 22 additions & 7 deletions packages/react/src/analytics-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,40 @@ export function schemaWrapper(schemaId: string, payload: object) {
* Parses global id (gid) and returns the resource type and id.
* @see https://shopify.dev/api/usage/gids
* @param gid - A shopify GID (string)
* @returns \{ id: number, resource: string \}
* @returns \{ id: string | number | null, resource: string| null \}
*
* @example
* ```ts
* const {id, resource} = parseGid('gid://shopify/Order/123')
* // => id = 123, resource = 'Order'
*
* * const {id, resource} = parseGid('gid://shopify/Cart/abc123')
* // => id = "abc123", resource = 'Cart'
* ```
**/
export function parseGid(gid: string | undefined): {
id: number | null;
id: string | number | null;
resource: string | null;
} {
if (typeof gid !== 'string') return {id: null, resource: null};
const matches = gid.match(/^gid:\/\/.hopify\/(\w+)\/(\d+)/);
const defaultReturn = {id: null, resource: null};

if (typeof gid !== 'string') {
return defaultReturn;
}

// TODO: add support for parsing query parameters on complex gids
const matches = gid.match(/^gid:\/\/.hopify\/(\w+)\/([a-z0-9]+)/);

if (!matches || matches.length === 1) {
return {id: null, resource: null};
return defaultReturn;
}
const id = matches[2] ?? null;
const resource = matches[1] ?? null;

// if id is of only numbers, return as an integer
if (id && /^\d+$/.test(id)) {
return {id: parseInt(id, 10), resource};
}
const id = matches[2] ? parseInt(matches[2], 10) : null;
const resource = matches[1] ? matches[1] : null;
return {id, resource};
}

Expand Down
31 changes: 31 additions & 0 deletions packages/react/src/cookie-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
buildUUID,
hexTime,
getShopifyCookies,
ShopifyCookies,
} from './cookies-utils.js';

describe('cookies-utils', () => {
describe('buildUUID', () => {
it('returns a string', () => {
expect(typeof buildUUID()).toBe('string');
});
});

describe('hexTime', () => {
it('returns a string', () => {
expect(typeof hexTime()).toBe('string');
});
});

describe('getShopifyCookies', () => {
it('returns object with SHOPIFY_Y and SHOPIFY_X', () => {
const cookie =
'_shopify_m=persistent; _y=44c60bb0-577c-4901-874c-92cb323fccf1; _shopify_y=44c60bb0-577c-4901-874c-92cb323fccf1; _shopify_y=44c60bb0-577c-4901-874c-92cb323fccf1; _tracking_consent={"lim":["GDPR"],"v":"2.0","con":{"GDPR":""},"reg":"CCPA"}; _shopify_s=a797b9ef-C0E7-4536-18BA-2828BA504882';
expect(getShopifyCookies(cookie)).toMatchObject<ShopifyCookies>({
_shopify_y: '44c60bb0-577c-4901-874c-92cb323fccf1',
_shopify_s: 'a797b9ef-C0E7-4536-18BA-2828BA504882',
});
});
});
});