Merge b9af6f6b9ae9c03b2c97e0e8216cc80244ee0343 into fa1306916c652ea5f820d5b400087bece13460fd

This commit is contained in:
Samandeep Bishnoi 2025-07-07 15:54:48 +00:00 committed by GitHub
commit 3e092c8d7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 2193 additions and 33 deletions

View File

@ -3,3 +3,4 @@ SITE_NAME="Next.js Commerce"
SHOPIFY_REVALIDATION_SECRET="" SHOPIFY_REVALIDATION_SECRET=""
SHOPIFY_STOREFRONT_ACCESS_TOKEN="" SHOPIFY_STOREFRONT_ACCESS_TOKEN=""
SHOPIFY_STORE_DOMAIN="[your-shopify-store-subdomain].myshopify.com" SHOPIFY_STORE_DOMAIN="[your-shopify-store-subdomain].myshopify.com"
SHOPIFY_STOREFRONT_API_VERSION= "2025-04"

View File

@ -28,4 +28,4 @@ export const TAGS = {
export const HIDDEN_PRODUCT_TAG = 'nextjs-frontend-hidden'; export const HIDDEN_PRODUCT_TAG = 'nextjs-frontend-hidden';
export const DEFAULT_OPTION = 'Default Title'; export const DEFAULT_OPTION = 'Default Title';
export const SHOPIFY_GRAPHQL_API_ENDPOINT = '/api/2023-01/graphql.json'; export const SHOPIFY_GRAPHQL_API_ENDPOINT = `/api/${process.env.SHOPIFY_STOREFRONT_API_VERSION}/graphql.json`;

View File

@ -61,8 +61,11 @@ import {
const domain = process.env.SHOPIFY_STORE_DOMAIN const domain = process.env.SHOPIFY_STORE_DOMAIN
? ensureStartsWith(process.env.SHOPIFY_STORE_DOMAIN, 'https://') ? ensureStartsWith(process.env.SHOPIFY_STORE_DOMAIN, 'https://')
: ''; : '';
const endpoint = `${domain}${SHOPIFY_GRAPHQL_API_ENDPOINT}`;
const key = process.env.SHOPIFY_STOREFRONT_ACCESS_TOKEN!; export const endpoint = `${domain}${SHOPIFY_GRAPHQL_API_ENDPOINT}`;
// Your Shopify Storefront access token
export const key = process.env.SHOPIFY_STOREFRONT_ACCESS_TOKEN!;
type ExtractVariables<T> = T extends { variables: object } type ExtractVariables<T> = T extends { variables: object }
? T['variables'] ? T['variables']
@ -76,7 +79,7 @@ export async function shopifyFetch<T>({
headers?: HeadersInit; headers?: HeadersInit;
query: string; query: string;
variables?: ExtractVariables<T>; variables?: ExtractVariables<T>;
}): Promise<{ status: number; body: T } | never> { }): Promise<{ status: number; body: T }> {
try { try {
const result = await fetch(endpoint, { const result = await fetch(endpoint, {
method: 'POST', method: 'POST',
@ -93,28 +96,35 @@ export async function shopifyFetch<T>({
const body = await result.json(); const body = await result.json();
// Handle API-level errors
if (body.errors) { if (body.errors) {
throw body.errors[0]; console.error('[shopifyFetch] Shopify API error:', {
query,
status: result.status,
error: body.errors[0]
});
// Throw a standard Error object (not a plain object)
throw new Error(
`Shopify API Error (${result.status}): ${body.errors[0].message}`
);
} }
return { return {
status: result.status, status: result.status,
body body
}; };
} catch (e) { } catch (err: any) {
if (isShopifyError(e)) { // Log full context for unknown or fetch-level errors
throw { console.error('[shopifyFetch] Unexpected fetch error:', {
cause: e.cause?.toString() || 'unknown', query,
status: e.status || 500, error: err
message: e.message, });
query
};
}
throw { // Re-throw a standard Error to be caught elsewhere
error: e, throw new Error(
query `Unexpected error in shopifyFetch: ${err?.message ?? err}`
}; );
} }
} }
@ -264,9 +274,11 @@ export async function updateCart(
} }
export async function getCart(): Promise<Cart | undefined> { export async function getCart(): Promise<Cart | undefined> {
try {
const cartId = (await cookies()).get('cartId')?.value; const cartId = (await cookies()).get('cartId')?.value;
if (!cartId) { if (!cartId) {
console.warn('[getCart] No cartId in cookies');
return undefined; return undefined;
} }
@ -275,12 +287,16 @@ export async function getCart(): Promise<Cart | undefined> {
variables: { cartId } variables: { cartId }
}); });
// Old carts becomes `null` when you checkout. if (!res.body?.data?.cart) {
if (!res.body.data.cart) { console.warn('[getCart] Cart is null for cartId:', cartId);
return undefined; return undefined;
} }
return reshapeCart(res.body.data.cart); return reshapeCart(res.body.data.cart);
} catch (err) {
console.error('[getCart] Failed:', err);
return undefined;
}
} }
export async function getCollection( export async function getCollection(

2143
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff