mirror of
https://github.com/vercel/commerce.git
synced 2025-07-24 10:41:23 +00:00
Intitial commit
This commit is contained in:
33
lib/sanity/sanity.api.ts
Normal file
33
lib/sanity/sanity.api.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* As this file is reused in several other files, try to keep it lean and small.
|
||||
* Importing other npm packages here could lead to needlessly increasing the client bundle size, or end up in a server-only function that don't need it.
|
||||
*/
|
||||
|
||||
export const dataset = assertValue(
|
||||
process.env.NEXT_PUBLIC_SANITY_DATASET,
|
||||
'Missing environment variable: NEXT_PUBLIC_SANITY_DATASET',
|
||||
)
|
||||
|
||||
export const projectId = assertValue(
|
||||
process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
|
||||
'Missing environment variable: NEXT_PUBLIC_SANITY_PROJECT_ID',
|
||||
)
|
||||
|
||||
// see https://www.sanity.io/docs/api-versioning for how versioning works
|
||||
export const apiVersion =
|
||||
process.env.NEXT_PUBLIC_SANITY_API_VERSION || '2023-06-21'
|
||||
|
||||
// This is the document id used for the preview secret that's stored in your dataset.
|
||||
// The secret protects against unauthorized access to your draft content and have a lifetime of 60 minutes, to protect against bruteforcing.
|
||||
export const previewSecretId: `${string}.${string}` = 'preview.secret'
|
||||
|
||||
// See the app/api/revalidate/route.ts for how this is used
|
||||
export const revalidateSecret = process.env.SANITY_REVALIDATE_SECRET
|
||||
|
||||
function assertValue<T>(v: T | undefined, errorMessage: string): T {
|
||||
if (v === undefined) {
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
@@ -1,31 +1,16 @@
|
||||
import type { SanityClient } from "@sanity/client";
|
||||
import { createClient } from "@sanity/client";
|
||||
import { cache } from "react";
|
||||
import { createClient } from 'next-sanity'
|
||||
import {
|
||||
apiVersion,
|
||||
dataset,
|
||||
projectId,
|
||||
revalidateSecret,
|
||||
} from './sanity.api'
|
||||
|
||||
export function getClient(preview?: {token?: string}): SanityClient {
|
||||
const client = createClient({
|
||||
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
|
||||
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
|
||||
apiVersion: process.env.NEXT_PUBLIC_SANITY_API_VERSION,
|
||||
useCdn: true,
|
||||
perspective: 'published',
|
||||
})
|
||||
if (preview) {
|
||||
if (!preview.token) {
|
||||
throw new Error('You must provide a token to preview drafts')
|
||||
}
|
||||
return client.withConfig({
|
||||
token: preview.token,
|
||||
useCdn: false,
|
||||
ignoreBrowserTokenWarning: true,
|
||||
perspective: 'previewDrafts',
|
||||
})
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
export const getCachedClient = (preview?: {token?: string}) => {
|
||||
const client = getClient(preview);
|
||||
|
||||
return cache(client.fetch.bind(client));
|
||||
};
|
||||
export const client = createClient({
|
||||
projectId,
|
||||
dataset,
|
||||
apiVersion,
|
||||
// If webhook revalidation is setup we want the freshest content, if not then it's best to use the speedy CDN
|
||||
useCdn: revalidateSecret ? false : true,
|
||||
perspective: 'published',
|
||||
})
|
61
lib/sanity/sanity.fetch.ts
Normal file
61
lib/sanity/sanity.fetch.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import 'server-only'
|
||||
|
||||
import type { QueryParams } from '@sanity/client'
|
||||
import { client } from './sanity.client'
|
||||
|
||||
import { draftMode } from 'next/headers'
|
||||
|
||||
import { revalidateSecret } from './sanity.api'
|
||||
|
||||
import { homePageQuery } from './queries'
|
||||
|
||||
import { HomePagePayload } from './sanity.types'
|
||||
|
||||
export const token = process.env.SANITY_API_READ_TOKEN
|
||||
|
||||
const DEFAULT_PARAMS = {} as QueryParams
|
||||
const DEFAULT_TAGS = [] as string[]
|
||||
|
||||
export async function sanityFetch<QueryResponse>({
|
||||
query,
|
||||
params = DEFAULT_PARAMS,
|
||||
tags = DEFAULT_TAGS,
|
||||
}: {
|
||||
query: string
|
||||
params?: QueryParams
|
||||
tags: string[]
|
||||
}): Promise<QueryResponse> {
|
||||
const isDraftMode = draftMode().isEnabled
|
||||
if (isDraftMode && !token) {
|
||||
throw new Error(
|
||||
'The `SANITY_API_READ_TOKEN` environment variable is required.',
|
||||
)
|
||||
}
|
||||
|
||||
// @TODO this won't be necessary after https://github.com/sanity-io/client/pull/299 lands
|
||||
const sanityClient =
|
||||
client.config().useCdn && isDraftMode
|
||||
? client.withConfig({ useCdn: false })
|
||||
: client
|
||||
return sanityClient.fetch<QueryResponse>(query, params, {
|
||||
// We only cache if there's a revalidation webhook setup
|
||||
cache: revalidateSecret ? 'force-cache' : 'no-store',
|
||||
...(isDraftMode && {
|
||||
cache: undefined,
|
||||
token: token,
|
||||
perspective: 'previewDrafts',
|
||||
}),
|
||||
next: {
|
||||
...(isDraftMode && { revalidate: 30 }),
|
||||
tags,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function getHomePage(locale: string) {
|
||||
return sanityFetch<HomePagePayload | null>({
|
||||
query: homePageQuery,
|
||||
params: { locale },
|
||||
tags: ['home', 'products', 'categories'],
|
||||
})
|
||||
}
|
@@ -1,7 +1,10 @@
|
||||
import createImageUrlBuilder from '@sanity/image-url'
|
||||
import { getClient } from './sanity.client'
|
||||
import { dataset, projectId } from './sanity.api'
|
||||
|
||||
export const imageBuilder = createImageUrlBuilder(getClient())
|
||||
const imageBuilder = createImageUrlBuilder({
|
||||
projectId: projectId || '',
|
||||
dataset: dataset || '',
|
||||
})
|
||||
|
||||
export const urlForImage = (source: any) =>
|
||||
imageBuilder.image(source).auto('format').fit('crop')
|
||||
|
12
lib/sanity/sanity.types.ts
Normal file
12
lib/sanity/sanity.types.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { Image } from 'sanity'
|
||||
|
||||
export interface HomePagePayload {
|
||||
content?: []
|
||||
title?: string
|
||||
_type?: string
|
||||
seo?: {
|
||||
title?: string;
|
||||
description?: string;
|
||||
image: Image
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user