Skip to content
This repository has been archived by the owner on Mar 3, 2023. It is now read-only.

Commit

Permalink
Fix bug in storefront client. (#125)
Browse files Browse the repository at this point in the history
Update the nextjs app to reflect that

Fix issue with latest graphql codegen needing ts-node

Add tests
  • Loading branch information
frehner committed Jan 18, 2023
1 parent 12b3239 commit 736cc41
Show file tree
Hide file tree
Showing 13 changed files with 292 additions and 55 deletions.
9 changes: 9 additions & 0 deletions .changeset/chilled-wombats-allow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@shopify/storefront-kit-react': patch
---

In the version 2023.1.1 "Breaking Changes" section, we said

> The storefront client and ShopifyProvider now provide the `storeDomain` exactly as it is received; it's recommended that you pass the domain with the protocol and the fully-qualified domain name for your Storefront. For example: `https://hydrogen-test.myshopify.com`
Unfortunately, the Storefront Client wasn't fully updated to actually do that. This update corrects this bug, but also means that you need to provide a full URL to your Storefront Domain (as was originally intended in our breaking change update).
4 changes: 2 additions & 2 deletions apps/nextjs/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ export function useFragment<TType>(
export function useFragment<TType>(
_documentNode: DocumentNode<TType, any>,
fragmentType: ReadonlyArray<FragmentType<DocumentNode<TType, any>>> | null | undefined
): ReadonlyArray<TType> | null | undefined
): ReadonlyArray<TType> | null | undefined;
export function useFragment<TType>(
_documentNode: DocumentNode<TType, any>,
fragmentType: FragmentType<DocumentNode<TType, any>> | ReadonlyArray<FragmentType<DocumentNode<TType, any>>> | null | undefined
): TType | ReadonlyArray<TType> | null | undefined {
return fragmentType as any
return fragmentType as any;
}


Expand Down
28 changes: 14 additions & 14 deletions apps/nextjs/gql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ const documents = {
"\n query Search($searchTerm: String) {\n products(first: 1, sortKey: RELEVANCE, query: $searchTerm) {\n pageInfo {\n startCursor\n endCursor\n hasNextPage\n hasPreviousPage\n }\n }\n }\n": types.SearchDocument,
};

/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*
*
* @example
* ```ts
* const query = gql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
* ```
*
* The query argument is unknown!
* Please regenerate the types.
*/
export function graphql(source: string): unknown;

/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand All @@ -36,20 +50,6 @@ export function graphql(source: "\n query Product {\n shop {\n name\n
*/
export function graphql(source: "\n query Search($searchTerm: String) {\n products(first: 1, sortKey: RELEVANCE, query: $searchTerm) {\n pageInfo {\n startCursor\n endCursor\n hasNextPage\n hasPreviousPage\n }\n }\n }\n"): (typeof documents)["\n query Search($searchTerm: String) {\n products(first: 1, sortKey: RELEVANCE, query: $searchTerm) {\n pageInfo {\n startCursor\n endCursor\n hasNextPage\n hasPreviousPage\n }\n }\n }\n"];

/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*
*
* @example
* ```ts
* const query = gql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
* ```
*
* The query argument is unknown!
* Please regenerate the types.
**/
export function graphql(source: string): unknown;

export function graphql(source: string) {
return (documents as any)[source] ?? {};
}
Expand Down
4 changes: 2 additions & 2 deletions apps/nextjs/gql/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from "./gql"
export * from "./fragment-masking"
export * from "./gql";
export * from "./fragment-masking";
2 changes: 1 addition & 1 deletion apps/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"react-dom": "18.2.0"
},
"devDependencies": {
"@graphql-codegen/cli": "2.16.4",
"@graphql-codegen/cli": "2.16.3",
"@graphql-codegen/client-preset": "1.2.6",
"@types/node": "18.11.18",
"@types/react": "18.0.26",
Expand Down
2 changes: 1 addition & 1 deletion apps/nextjs/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default function App({Component, pageProps}: AppProps) {
return (
<ShopifyProvider
shopifyConfig={{
storeDomain: `hydrogen-preview`,
storeDomain: `https://hydrogen-preview.myshopify.com`,
storefrontToken: '3b580e70970c4528da70c98e097c2fa0',
storefrontApiVersion: '2023-01',
locale: 'EN-US',
Expand Down
2 changes: 1 addition & 1 deletion apps/nextjs/src/shopify-client.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {createStorefrontClient} from '@shopify/storefront-kit-react';

export const shopClient = createStorefrontClient({
storeDomain: 'hydrogen-preview',
storeDomain: 'https://hydrogen-preview.myshopify.com',
// TODO: convert to 'privateStorefrontToken'!
publicStorefrontToken: '3b580e70970c4528da70c98e097c2fa0',
storefrontApiVersion: '2023-01',
Expand Down
2 changes: 1 addition & 1 deletion packages/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# React Storefront Kit

React Storefront Kit provides React components, reusable functions, and utilities for interacting with the Storefront API.
React Storefront Kit provides React components, reusable functions, and utilities for interacting with the Storefront API.

**IMPORTANT:** Refer to how this package is [versioned](../../README.md#versioning).

Expand Down
61 changes: 61 additions & 0 deletions packages/react/src/ShopifyProvider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,67 @@ describe('<ShopifyProvider/>', () => {
).toBe('https://test.myshopify.com');
});
});

describe(`getStorefrontApiUrl`, () => {
it(`generates the API URL`, () => {
const {result} = renderHook(() => useShop(), {
wrapper: ({children}) => (
<ShopifyProvider
shopifyConfig={{
...SHOPIFY_CONFIG,
storeDomain: 'https://notashop.myshopify.com',
}}
>
{children}
</ShopifyProvider>
),
});

expect(result.current.getStorefrontApiUrl()).toBe(
'https://notashop.myshopify.com/api/2023-01/graphql.json'
);
});

it(`allows overrides`, () => {
const {result} = renderHook(() => useShop(), {
wrapper: ({children}) => (
<ShopifyProvider
shopifyConfig={{
...SHOPIFY_CONFIG,
storeDomain: 'https://notashop.myshopify.com',
}}
>
{children}
</ShopifyProvider>
),
});

expect(
result.current.getStorefrontApiUrl({
storeDomain: 'https://test.myshopify.com',
})
).toBe('https://test.myshopify.com/api/2023-01/graphql.json');
});

it(`handles when a '/' is at the end of the url and doesn't add an extra one`, () => {
const {result} = renderHook(() => useShop(), {
wrapper: ({children}) => (
<ShopifyProvider
shopifyConfig={{
...SHOPIFY_CONFIG,
storeDomain: 'https://notashop.myshopify.com/',
}}
>
{children}
</ShopifyProvider>
),
});

expect(result.current.getStorefrontApiUrl()).toBe(
'https://notashop.myshopify.com/api/2023-01/graphql.json'
);
});
});
});

export function getShopifyConfig(
Expand Down
14 changes: 5 additions & 9 deletions packages/react/src/ShopifyProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,12 @@ export function ShopifyProvider({
},
getShopifyDomain,
getStorefrontApiUrl(overrideProps) {
if (overrideProps?.storeDomain?.includes('.myshopify.com')) {
if (__HYDROGEN_DEV__) {
console.warn(
`<ShopifyProvider/>: passing a 'storeDomain' prop that includes '.myshopify.com' will be unsupported in the future. Passing only the subdomain (for example, if the URL is 'test.myshopify.com', passing in 'test') will be the supported way going forward.`
);
}
}
return `${getShopifyDomain({
const finalDomainUrl = getShopifyDomain({
storeDomain: overrideProps?.storeDomain ?? shopifyConfig.storeDomain,
})}/api/${
});
return `${finalDomainUrl}${
finalDomainUrl.endsWith('/') ? '' : '/'
}api/${
overrideProps?.storefrontApiVersion ??
shopifyConfig.storefrontApiVersion
}/graphql.json`;
Expand Down
18 changes: 15 additions & 3 deletions packages/react/src/storefront-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe(`createStorefrontClient`, () => {

expect(
client.getShopifyDomain({
storeDomain: 'newdomain',
storeDomain: 'https://newdomain.myshopify.com',
})
).toBe(`https://newdomain.myshopify.com`);
});
Expand All @@ -79,11 +79,23 @@ describe(`createStorefrontClient`, () => {

expect(
client.getStorefrontApiUrl({
storeDomain: 'newdomain',
storeDomain: 'https://newdomain.myshopify.com',
storefrontApiVersion: '2000-01',
})
).toBe(`https://newdomain.myshopify.com/api/2000-01/graphql.json`);
});

it(`handles when a '/' is at the end of the url and doesn't add an extra one`, () => {
const defaultConfig = generateConfig();
const client = createStorefrontClient({
...defaultConfig,
storeDomain: defaultConfig.storeDomain + '/',
});

expect(client.getStorefrontApiUrl()).toBe(
`https://testing.myshopify.com/api/${SFAPI_VERSION}/graphql.json`
);
});
});

describe(`getPrivateTokenHeaders`, () => {
Expand Down Expand Up @@ -166,7 +178,7 @@ function generateConfig(
): StorefrontClientProps {
return {
storefrontApiVersion: SFAPI_VERSION,
storeDomain: 'testing',
storeDomain: 'https://testing.myshopify.com',
...props,
};
}
9 changes: 3 additions & 6 deletions packages/react/src/storefront-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,11 @@ export function createStorefrontClient({

return {
getShopifyDomain(overrideProps) {
return `https://${
overrideProps?.storeDomain ?? storeDomain
}.myshopify.com`;
return overrideProps?.storeDomain ?? storeDomain;
},
getStorefrontApiUrl(overrideProps) {
return `https://${
overrideProps?.storeDomain ?? storeDomain
}.myshopify.com/api/${
const finalDomainUrl = overrideProps?.storeDomain ?? storeDomain;
return `${finalDomainUrl}${finalDomainUrl.endsWith('/') ? '' : '/'}api/${
overrideProps?.storefrontApiVersion ?? storefrontApiVersion
}/graphql.json`;
},
Expand Down

0 comments on commit 736cc41

Please sign in to comment.