Merge branch 'master' into feature/tracking
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import "server-only"
|
||||
|
||||
import { ContentstackLivePreview } from "@contentstack/live-preview-utils"
|
||||
import { ClientError, GraphQLClient } from "graphql-request"
|
||||
|
||||
import { Lang } from "@/constants/languages"
|
||||
@@ -20,51 +19,38 @@ export async function request<T>(
|
||||
client.setHeaders({
|
||||
access_token: env.CMS_ACCESS_TOKEN,
|
||||
"Content-Type": "application/json",
|
||||
...params?.headers,
|
||||
})
|
||||
|
||||
const previewHash = ContentstackLivePreview.hash
|
||||
if (previewHash) {
|
||||
client.setEndpoint(env.CMS_PREVIEW_URL)
|
||||
client.setHeader("preview_token", env.CMS_PREVIEW_TOKEN)
|
||||
client.setHeader("live_preview", previewHash)
|
||||
} else {
|
||||
if (params?.cache) {
|
||||
client.requestConfig.cache = params.cache
|
||||
}
|
||||
if (params?.headers) {
|
||||
client.requestConfig.headers = params.headers
|
||||
}
|
||||
if (params?.next) {
|
||||
client.requestConfig.next = params.next
|
||||
}
|
||||
client.requestConfig.cache = params?.cache
|
||||
client.requestConfig.next = params?.next
|
||||
|
||||
if (env.PRINT_QUERY) {
|
||||
const print = (await import("graphql/language/printer")).print
|
||||
const rawResponse = await client.rawRequest<T>(
|
||||
print(query as DocumentNode),
|
||||
variables,
|
||||
{
|
||||
access_token: env.CMS_ACCESS_TOKEN,
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* TODO: Send to Monitoring (Logging and Metrics)
|
||||
*/
|
||||
console.log({
|
||||
complexityLimit: rawResponse.headers.get("x-query-complexity"),
|
||||
})
|
||||
console.log({
|
||||
referenceDepth: rawResponse.headers.get("x-reference-depth"),
|
||||
})
|
||||
console.log({
|
||||
resolverCost: rawResponse.headers.get("x-resolver-cost"),
|
||||
})
|
||||
|
||||
return {
|
||||
data: rawResponse.data,
|
||||
if (env.PRINT_QUERY) {
|
||||
const print = (await import("graphql/language/printer")).print
|
||||
const rawResponse = await client.rawRequest<T>(
|
||||
print(query as DocumentNode),
|
||||
variables,
|
||||
{
|
||||
access_token: env.CMS_ACCESS_TOKEN,
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* TODO: Send to Monitoring (Logging and Metrics)
|
||||
*/
|
||||
console.log({
|
||||
complexityLimit: rawResponse.headers.get("x-query-complexity"),
|
||||
})
|
||||
console.log({
|
||||
referenceDepth: rawResponse.headers.get("x-reference-depth"),
|
||||
})
|
||||
console.log({
|
||||
resolverCost: rawResponse.headers.get("x-resolver-cost"),
|
||||
})
|
||||
|
||||
return {
|
||||
data: rawResponse.data,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,14 +7,15 @@ import { request as _request } from "./_request"
|
||||
|
||||
import { Data } from "@/types/request"
|
||||
|
||||
const client = new GraphQLClient(env.CMS_URL, {
|
||||
fetch: fetch,
|
||||
})
|
||||
|
||||
export async function edgeRequest<T>(
|
||||
query: string | DocumentNode,
|
||||
variables?: {},
|
||||
params?: RequestInit
|
||||
): Promise<Data<T>> {
|
||||
// Creating a new client for each request to avoid conflicting parameters
|
||||
const client = new GraphQLClient(env.CMS_URL, {
|
||||
fetch: fetch,
|
||||
})
|
||||
|
||||
return _request(client, query, variables, params)
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import "server-only"
|
||||
|
||||
import { ContentstackLivePreview } from "@contentstack/live-preview-utils"
|
||||
import { request as graphqlRequest } from "graphql-request"
|
||||
|
||||
import { env } from "@/env/server"
|
||||
|
||||
import type { DocumentNode } from "graphql"
|
||||
|
||||
import type { Data } from "@/types/request"
|
||||
|
||||
export async function previewRequest<T>(
|
||||
query: string | DocumentNode,
|
||||
variables?: {}
|
||||
): Promise<Data<T>> {
|
||||
try {
|
||||
const hash = ContentstackLivePreview.hash
|
||||
|
||||
if (!hash) {
|
||||
throw new Error("No hash received")
|
||||
}
|
||||
|
||||
const headers = new Headers({
|
||||
access_token: env.CMS_ACCESS_TOKEN,
|
||||
preview_token: env.CMS_PREVIEW_TOKEN,
|
||||
live_preview: hash,
|
||||
})
|
||||
|
||||
const response = await graphqlRequest<T>({
|
||||
document: query,
|
||||
requestHeaders: headers,
|
||||
url: env.CMS_PREVIEW_URL,
|
||||
variables,
|
||||
})
|
||||
|
||||
return { data: response }
|
||||
} catch (error) {
|
||||
console.error("Error in preview graphql request")
|
||||
console.error(error)
|
||||
throw new Error("Something went wrong")
|
||||
}
|
||||
}
|
||||
@@ -4,30 +4,49 @@ import { GraphQLClient } from "graphql-request"
|
||||
import { cache } from "react"
|
||||
|
||||
import { env } from "@/env/server"
|
||||
import { getPreviewHash, isPreviewByUid } from "@/lib/previewContext"
|
||||
|
||||
import { request as _request } from "./_request"
|
||||
|
||||
import { Data } from "@/types/request"
|
||||
|
||||
const client = new GraphQLClient(env.CMS_URL, {
|
||||
fetch: cache(async function (
|
||||
url: URL | RequestInfo,
|
||||
params: RequestInit | undefined
|
||||
) {
|
||||
const wrappedFetch = fetchRetry(fetch, {
|
||||
retries: 3,
|
||||
retryDelay: function (attempt, error, response) {
|
||||
return Math.pow(2, attempt) * 150 // 150, 300, 600
|
||||
},
|
||||
})
|
||||
return wrappedFetch(url, params)
|
||||
}),
|
||||
})
|
||||
|
||||
export async function request<T>(
|
||||
query: string | DocumentNode,
|
||||
variables?: {},
|
||||
variables?: Record<string, any>,
|
||||
params?: RequestInit
|
||||
): Promise<Data<T>> {
|
||||
return _request(client, query, variables, params)
|
||||
const shouldUsePreview = variables?.uid
|
||||
? isPreviewByUid(variables.uid)
|
||||
: false
|
||||
const previewHash = getPreviewHash()
|
||||
const cmsUrl = shouldUsePreview ? env.CMS_PREVIEW_URL : env.CMS_URL
|
||||
|
||||
// Creating a new client for each request to avoid conflicting parameters
|
||||
const client = new GraphQLClient(cmsUrl, {
|
||||
fetch: cache(async function (url: URL | RequestInfo, params?: RequestInit) {
|
||||
const wrappedFetch = fetchRetry(fetch, {
|
||||
retries: 3,
|
||||
retryDelay: function (attempt, error, response) {
|
||||
return Math.pow(2, attempt) * 150 // 150, 300, 600
|
||||
},
|
||||
})
|
||||
return wrappedFetch(url, params)
|
||||
}),
|
||||
})
|
||||
|
||||
const mergedParams =
|
||||
shouldUsePreview && previewHash
|
||||
? {
|
||||
...params,
|
||||
headers: {
|
||||
...params?.headers,
|
||||
live_preview: previewHash,
|
||||
preview_token: env.CMS_PREVIEW_TOKEN,
|
||||
},
|
||||
cache: undefined,
|
||||
next: undefined,
|
||||
}
|
||||
: params
|
||||
|
||||
return _request(client, query, variables, mergedParams)
|
||||
}
|
||||
|
||||
42
lib/previewContext.ts
Normal file
42
lib/previewContext.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { cache } from "react"
|
||||
|
||||
interface PreviewData {
|
||||
hash: string
|
||||
uid: string
|
||||
}
|
||||
|
||||
const getRef = cache((): { current?: PreviewData } => ({
|
||||
current: undefined,
|
||||
}))
|
||||
|
||||
/**
|
||||
* Set the preview hash for the current request
|
||||
*
|
||||
* It works kind of like React's context,
|
||||
* but on the server side, per request.
|
||||
*
|
||||
* @param hash
|
||||
*/
|
||||
export function setPreviewData(data?: PreviewData) {
|
||||
getRef().current = data
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preview hash set for the current request
|
||||
*/
|
||||
export function getPreviewHash() {
|
||||
return getRef().current?.hash
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current request is a preview by comparing the uid
|
||||
*/
|
||||
export function isPreviewByUid(uid: string) {
|
||||
const data = getRef().current
|
||||
|
||||
if (data?.hash) {
|
||||
return data.uid === uid
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
@@ -143,3 +143,9 @@ export const getBreakfastPackages = cache(async function getMemoizedPackages(
|
||||
) {
|
||||
return serverClient().hotel.packages.breakfast(input)
|
||||
})
|
||||
|
||||
export const getBookingConfirmation = cache(
|
||||
function getMemoizedBookingConfirmation(confirmationNumber: string) {
|
||||
return serverClient().booking.confirmation({ confirmationNumber })
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user