next-drupal
Version:
Helpers for Next.js + Drupal.
1 lines • 149 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts","../src/draft-constants.ts","../src/jsonapi-errors.ts","../src/next-drupal-base.ts","../src/logger.ts","../src/next-drupal.ts","../src/menu-tree.ts","../src/next-drupal-pages.ts","../src/deprecated/get-cache.ts","../src/deprecated/get-access-token.ts","../src/deprecated/utils.ts","../src/deprecated/get-menu.ts","../src/deprecated/get-resource-collection.ts","../src/deprecated/get-paths.ts","../src/deprecated/get-resource.ts","../src/deprecated/preview.ts","../src/deprecated/translate-path.ts","../src/deprecated/get-resource-type.ts","../src/deprecated/get-search-index.ts","../src/deprecated/get-view.ts","../src/deprecated.ts"],"sourcesContent":["export * from \"./draft-constants\"\nexport * from \"./jsonapi-errors\"\nexport * from \"./next-drupal-base\"\nexport * from \"./next-drupal\"\nexport * from \"./next-drupal-pages\"\n\nexport type * from \"./types\"\n\nexport * from \"./deprecated\"\n","export const DRAFT_DATA_COOKIE_NAME = \"next_drupal_draft_data\"\n\n// See https://vercel.com/docs/workflow-collaboration/draft-mode\nexport const DRAFT_MODE_COOKIE_NAME = \"__prerender_bypass\"\n","// https://jsonapi.org/format/#error-objects\nexport interface JsonApiError {\n id?: string\n status?: string\n code?: string\n title?: string\n detail?: string\n links?: JsonApiLinks\n}\n\n// https://jsonapi.org/format/#document-links\nexport interface JsonApiLinks {\n [key: string]: string | Record<string, string>\n}\n\n/** @hidden */\nexport class JsonApiErrors extends Error {\n errors: JsonApiError[] | string\n statusCode: number\n\n constructor(\n errors: JsonApiError[] | string,\n statusCode: number,\n messagePrefix: string = \"\"\n ) {\n super()\n\n this.errors = errors\n this.statusCode = statusCode\n this.message =\n (messagePrefix ? `${messagePrefix} ` : \"\") +\n JsonApiErrors.formatMessage(errors)\n }\n\n static formatMessage(errors: JsonApiError[] | string) {\n if (typeof errors === \"string\") {\n return errors\n }\n\n const [error] = errors\n\n let message = `${error.status} ${error.title}`\n\n if (error.detail) {\n message += `\\n${error.detail}`\n }\n\n return message\n }\n}\n","import { stringify } from \"qs\"\nimport { JsonApiErrors } from \"./jsonapi-errors\"\nimport { logger as defaultLogger } from \"./logger\"\nimport type {\n AccessToken,\n BaseUrl,\n EndpointSearchParams,\n FetchOptions,\n JsonApiResponse,\n Locale,\n Logger,\n NextDrupalAuth,\n NextDrupalAuthAccessToken,\n NextDrupalAuthClientIdSecret,\n NextDrupalAuthUsernamePassword,\n NextDrupalBaseOptions,\n PathPrefix,\n} from \"./types\"\n\nconst DEFAULT_API_PREFIX = \"\"\nconst DEFAULT_FRONT_PAGE = \"/home\"\nconst DEFAULT_WITH_AUTH = false\n\n// From simple_oauth.\nconst DEFAULT_AUTH_URL = \"/oauth/token\"\n\n// See https://jsonapi.org/format/#content-negotiation.\nconst DEFAULT_HEADERS = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n}\n\n/**\n * The base class for NextDrupal clients.\n */\nexport class NextDrupalBase {\n accessToken?: NextDrupalBaseOptions[\"accessToken\"]\n\n baseUrl: BaseUrl\n\n fetcher?: NextDrupalBaseOptions[\"fetcher\"]\n\n frontPage: string\n\n isDebugEnabled: boolean\n\n logger: Logger\n\n withAuth: boolean\n\n private _apiPrefix: string\n\n private _auth?: NextDrupalAuth\n\n private _headers: Headers\n\n private _token?: AccessToken\n\n private _tokenExpiresOn?: number\n\n private _tokenRequestDetails?: NextDrupalAuthClientIdSecret\n\n /**\n * Instantiates a new NextDrupalBase.\n *\n * const client = new NextDrupalBase(baseUrl)\n *\n * @param {baseUrl} baseUrl The baseUrl of your Drupal site. Do not add the /jsonapi suffix.\n * @param {options} options Options for NextDrupalBase.\n */\n constructor(baseUrl: BaseUrl, options: NextDrupalBaseOptions = {}) {\n if (!baseUrl || typeof baseUrl !== \"string\") {\n throw new Error(\"The 'baseUrl' param is required.\")\n }\n\n const {\n accessToken,\n apiPrefix = DEFAULT_API_PREFIX,\n auth,\n debug = false,\n fetcher,\n frontPage = DEFAULT_FRONT_PAGE,\n headers = DEFAULT_HEADERS,\n logger = defaultLogger,\n withAuth = DEFAULT_WITH_AUTH,\n } = options\n\n this.accessToken = accessToken\n this.apiPrefix = apiPrefix\n this.auth = auth\n this.baseUrl = baseUrl\n this.fetcher = fetcher\n this.frontPage = frontPage\n this.isDebugEnabled = !!debug\n this.headers = headers\n this.logger = logger\n this.withAuth = withAuth\n\n this.debug(\"Debug mode is on.\")\n }\n\n set apiPrefix(apiPrefix: string) {\n this._apiPrefix =\n apiPrefix === \"\" || apiPrefix.startsWith(\"/\")\n ? apiPrefix\n : `/${apiPrefix}`\n }\n\n get apiPrefix() {\n return this._apiPrefix\n }\n\n set auth(auth: NextDrupalAuth) {\n if (typeof auth === \"object\") {\n const checkUsernamePassword = auth as NextDrupalAuthUsernamePassword\n const checkAccessToken = auth as NextDrupalAuthAccessToken\n const checkClientIdSecret = auth as NextDrupalAuthClientIdSecret\n\n if (\n checkUsernamePassword.username !== undefined ||\n checkUsernamePassword.password !== undefined\n ) {\n if (\n !checkUsernamePassword.username ||\n !checkUsernamePassword.password\n ) {\n throw new Error(\n \"'username' and 'password' are required for auth. See https://next-drupal.org/docs/client/auth\"\n )\n }\n } else if (\n checkAccessToken.access_token !== undefined ||\n checkAccessToken.token_type !== undefined\n ) {\n if (!checkAccessToken.access_token || !checkAccessToken.token_type) {\n throw new Error(\n \"'access_token' and 'token_type' are required for auth. See https://next-drupal.org/docs/client/auth\"\n )\n }\n } else if (\n !checkClientIdSecret.clientId ||\n !checkClientIdSecret.clientSecret\n ) {\n throw new Error(\n \"'clientId' and 'clientSecret' are required for auth. See https://next-drupal.org/docs/client/auth\"\n )\n }\n\n this._auth = {\n ...(isClientIdSecretAuth(auth) ? { url: DEFAULT_AUTH_URL } : {}),\n ...auth,\n }\n } else {\n this._auth = auth\n }\n }\n\n get auth() {\n return this._auth\n }\n\n set headers(headers: HeadersInit) {\n this._headers = new Headers(headers)\n }\n\n get headers() {\n return this._headers\n }\n\n set token(token: AccessToken) {\n this._token = token\n this._tokenExpiresOn = Date.now() + token.expires_in * 1000\n }\n\n get token() {\n return this._token\n }\n\n /**\n * Fetches a resource from the given input URL or path.\n *\n * @param {RequestInfo} input The url to fetch from.\n * @param {FetchOptions} init The fetch options with `withAuth`.\n * If `withAuth` is set, `fetch` will fetch an `Authorization` header before making the request.\n * @returns {Promise<Response>} The fetch response.\n * @remarks\n * To provide your own custom fetcher, see the fetcher docs.\n * @example\n * ```ts\n * const url = drupal.buildUrl(\"/jsonapi/node/article\", {\n * sort: \"-created\",\n * \"fields[node--article]\": \"title,path\",\n * })\n *\n * const response = await drupal.fetch(url.toString())\n * ```\n */\n async fetch(\n input: RequestInfo,\n { withAuth, ...init }: FetchOptions = {}\n ): Promise<Response> {\n init.credentials = \"include\"\n\n // Merge the init.headers with this.headers\n const headers = new Headers(this.headers)\n if (init?.headers) {\n const initHeaders = new Headers(init?.headers)\n for (const key of initHeaders.keys()) {\n headers.set(key, initHeaders.get(key))\n }\n }\n\n // Set Authorization header.\n if (withAuth) {\n headers.set(\n \"Authorization\",\n await this.getAuthorizationHeader(\n withAuth === true ? this.auth : withAuth\n )\n )\n }\n\n init.headers = headers\n\n if (typeof input === \"string\" && input.startsWith(\"/\")) {\n input = `${this.baseUrl}${input}`\n }\n\n if (this.fetcher) {\n this.debug(`Using custom fetcher, fetching: ${input}`)\n\n return await this.fetcher(input, init)\n }\n\n this.debug(`Using default fetch, fetching: ${input}`)\n\n return await fetch(input, init)\n }\n\n /**\n * Gets the authorization header value based on the provided auth configuration.\n *\n * @param {NextDrupalAuth} auth The auth configuration.\n * @returns {Promise<string>} The authorization header value.\n */\n async getAuthorizationHeader(auth: NextDrupalAuth) {\n let header: string\n\n if (isBasicAuth(auth)) {\n const basic = Buffer.from(`${auth.username}:${auth.password}`).toString(\n \"base64\"\n )\n header = `Basic ${basic}`\n this.debug(\"Using basic authorization header.\")\n } else if (isClientIdSecretAuth(auth)) {\n // Fetch an access token and add it to the request. getAccessToken()\n // throws an error if it fails to get an access token.\n const token = await this.getAccessToken(auth)\n header = `Bearer ${token.access_token}`\n this.debug(\n \"Using access token authorization header retrieved from Client Id/Secret.\"\n )\n } else if (isAccessTokenAuth(auth)) {\n header = `${auth.token_type} ${auth.access_token}`\n this.debug(\"Using access token authorization header.\")\n } else if (typeof auth === \"string\") {\n header = auth\n this.debug(\"Using custom authorization header.\")\n } else if (typeof auth === \"function\") {\n header = auth()\n this.debug(\"Using custom authorization callback.\")\n } else {\n throw new Error(\n \"auth is not configured. See https://next-drupal.org/docs/client/auth\"\n )\n }\n\n return header\n }\n\n /**\n * Builds a URL with the given path and search parameters.\n *\n * @param {string} path The path for the url. Example: \"/example\"\n * @param {string | Record<string, string> | URLSearchParams | JsonApiParams} searchParams Optional query parameters.\n * @returns {URL} The constructed URL.\n * @example\n * ```ts\n * const drupal = new DrupalClient(\"https://example.com\")\n *\n * // https://drupal.org\n * drupal.buildUrl(\"https://drupal.org\").toString()\n *\n * // https://example.com/foo\n * drupal.buildUrl(\"/foo\").toString()\n *\n * // https://example.com/foo?bar=baz\n * client.buildUrl(\"/foo\", { bar: \"baz\" }).toString()\n * ```\n *\n * Build a URL from `DrupalJsonApiParams`\n * ```ts\n * const params = {\n * getQueryObject: () => ({\n * sort: \"-created\",\n * \"fields[node--article]\": \"title,path\",\n * }),\n * }\n *\n * // https://example.com/jsonapi/node/article?sort=-created&fields%5Bnode--article%5D=title%2Cpath\n * drupal.buildUrl(\"/jsonapi/node/article\", params).toString()\n * ```\n */\n buildUrl(path: string, searchParams?: EndpointSearchParams): URL {\n const url = new URL(path, this.baseUrl)\n\n const search =\n // Handle DrupalJsonApiParams objects.\n searchParams &&\n typeof searchParams === \"object\" &&\n \"getQueryObject\" in searchParams\n ? searchParams.getQueryObject()\n : searchParams\n\n if (search) {\n // Use stringify instead of URLSearchParams for nested params.\n url.search = stringify(search)\n }\n\n return url\n }\n\n /**\n * Builds an endpoint URL with the given options.\n *\n * @param {Object} options The options for building the endpoint.\n * @param {string} options.locale The locale.\n * @param {string} options.path The path.\n * @param {EndpointSearchParams} options.searchParams The search parameters.\n * @returns {Promise<string>} The constructed endpoint URL.\n */\n async buildEndpoint({\n locale = \"\",\n path = \"\",\n searchParams,\n }: {\n locale?: string\n path?: string\n searchParams?: EndpointSearchParams\n } = {}): Promise<string> {\n const localeSegment = locale ? `/${locale}` : \"\"\n\n if (path && !path.startsWith(\"/\")) {\n path = `/${path}`\n }\n\n return this.buildUrl(\n `${localeSegment}${this.apiPrefix}${path}`,\n searchParams\n ).toString()\n }\n\n /**\n * Constructs a path from the given segment and options.\n *\n * @param {string | string[]} segment The path segment.\n * @param {Object} options The options for constructing the path.\n * @param {Locale} options.locale The locale.\n * @param {Locale} options.defaultLocale The default locale.\n * @param {PathPrefix} options.pathPrefix The path prefix.\n * @returns {string} The constructed path.\n */\n constructPathFromSegment(\n segment: string | string[],\n options: {\n locale?: Locale\n defaultLocale?: Locale\n pathPrefix?: PathPrefix\n } = {}\n ) {\n let { pathPrefix = \"\" } = options\n const { locale, defaultLocale } = options\n\n // Ensure pathPrefix starts with a \"/\" and does not end with a \"/\".\n if (pathPrefix) {\n if (!pathPrefix?.startsWith(\"/\")) {\n pathPrefix = `/${options.pathPrefix}`\n }\n if (pathPrefix.endsWith(\"/\")) {\n pathPrefix = pathPrefix.slice(0, -1)\n }\n }\n\n // If the segment is given as an array of segments, join the parts.\n if (!Array.isArray(segment)) {\n segment = segment ? [segment] : []\n }\n segment = segment.map((part) => encodeURIComponent(part)).join(\"/\")\n\n if (!segment && !pathPrefix) {\n // If no pathPrefix is given and the segment is empty, then the path\n // should be the homepage.\n segment = this.frontPage\n }\n\n // Ensure the segment starts with a \"/\" and does not end with a \"/\".\n if (segment && !segment.startsWith(\"/\")) {\n segment = `/${segment}`\n }\n if (segment.endsWith(\"/\")) {\n segment = segment.slice(0, -1)\n }\n\n return this.addLocalePrefix(`${pathPrefix}${segment}`, {\n locale,\n defaultLocale,\n })\n }\n\n /**\n * Adds a locale prefix to the given path.\n *\n * @param {string} path The path.\n * @param {Object} options The options for adding the locale prefix.\n * @param {Locale} options.locale The locale.\n * @param {Locale} options.defaultLocale The default locale.\n * @returns {string} The path with the locale prefix.\n */\n addLocalePrefix(\n path: string,\n options: { locale?: Locale; defaultLocale?: Locale } = {}\n ) {\n const { locale, defaultLocale } = options\n\n if (!path.startsWith(\"/\")) {\n path = `/${path}`\n }\n\n let localePrefix = \"\"\n if (locale && !path.startsWith(`/${locale}`) && locale !== defaultLocale) {\n localePrefix = `/${locale}`\n }\n\n return `${localePrefix}${path}`\n }\n\n /**\n * Retrieve an access token.\n *\n * @param {NextDrupalAuthClientIdSecret} clientIdSecret The client ID and secret.\n * @returns {Promise<AccessToken>} The access token.\n * @remarks\n * If options is not provided, `DrupalClient` will use the `clientId` and `clientSecret` configured in `auth`.\n * @example\n * ```ts\n * const accessToken = await drupal.getAccessToken({\n * clientId: \"7034f4db-7151-466f-a711-8384bddb9e60\",\n * clientSecret: \"d92Fm^ds\",\n * })\n * ```\n */\n async getAccessToken(\n clientIdSecret?: NextDrupalAuthClientIdSecret\n ): Promise<AccessToken> {\n if (this.accessToken) {\n return this.accessToken\n }\n\n let auth: NextDrupalAuthClientIdSecret\n if (isClientIdSecretAuth(clientIdSecret)) {\n auth = {\n url: DEFAULT_AUTH_URL,\n ...clientIdSecret,\n }\n } else if (isClientIdSecretAuth(this.auth)) {\n auth = { ...this.auth }\n } else if (typeof this.auth === \"undefined\") {\n throw new Error(\n \"auth is not configured. See https://next-drupal.org/docs/client/auth\"\n )\n } else {\n throw new Error(\n `'clientId' and 'clientSecret' required. See https://next-drupal.org/docs/client/auth`\n )\n }\n\n const url = this.buildUrl(auth.url)\n\n // Ensure that the unexpired token was using the same scope and client\n // credentials as the current request before re-using it.\n if (\n this.token &&\n Date.now() < this._tokenExpiresOn &&\n this._tokenRequestDetails?.clientId === auth?.clientId &&\n this._tokenRequestDetails?.clientSecret === auth?.clientSecret &&\n this._tokenRequestDetails?.scope === auth?.scope\n ) {\n this.debug(`Using existing access token.`)\n return this.token\n }\n\n this.debug(`Fetching new access token.`)\n\n // Use BasicAuth to retrieve the access token.\n const clientCredentials: NextDrupalAuthUsernamePassword = {\n username: auth.clientId,\n password: auth.clientSecret,\n }\n const body = new URLSearchParams({ grant_type: \"client_credentials\" })\n\n if (auth?.scope) {\n body.set(\"scope\", auth.scope)\n\n this.debug(`Using scope: ${auth.scope}`)\n }\n\n const response = await this.fetch(url.toString(), {\n method: \"POST\",\n headers: {\n Authorization: await this.getAuthorizationHeader(clientCredentials),\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body,\n })\n\n await this.throwIfJsonErrors(\n response,\n \"Error while fetching new access token: \"\n )\n\n const result: AccessToken = await response.json()\n\n this.token = result\n\n this._tokenRequestDetails = auth\n\n return result\n }\n\n /**\n * Validates the draft URL using the provided search parameters.\n *\n * @param {URLSearchParams} searchParams The search parameters.\n * @returns {Promise<Response>} The validation response.\n */\n async validateDraftUrl(searchParams: URLSearchParams): Promise<Response> {\n const path = searchParams.get(\"path\")\n\n this.debug(`Fetching draft url validation for ${path}.`)\n\n // Fetch the headless CMS to check if the provided `path` exists\n let response: Response\n try {\n // Validate the draft url.\n const validateUrl = this.buildUrl(\"/next/draft-url\").toString()\n response = await this.fetch(validateUrl, {\n method: \"POST\",\n headers: {\n Accept: \"application/vnd.api+json\",\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(Object.fromEntries(searchParams.entries())),\n })\n } catch (error) {\n response = new Response(JSON.stringify({ message: error.message }), {\n status: 401,\n })\n }\n\n this.debug(\n response.status !== 200\n ? `Could not validate path, ${path}`\n : `Validated path, ${path}`\n )\n\n return response\n }\n\n /**\n * Logs a debug message if debug mode is enabled.\n *\n * @param {string} message The debug message.\n */\n debug(message) {\n this.isDebugEnabled && this.logger.debug(message)\n }\n\n /**\n * Throws an error if the response contains JSON:API errors.\n *\n * @param {Response} response The fetch response.\n * @param {string} messagePrefix The error message prefix.\n * @throws {JsonApiErrors} The JSON:API errors.\n */\n async throwIfJsonErrors(response: Response, messagePrefix = \"\") {\n if (!response?.ok) {\n const errors = await this.getErrorsFromResponse(response)\n throw new JsonApiErrors(errors, response.status, messagePrefix)\n }\n }\n\n /**\n * Extracts errors from the fetch response.\n *\n * @param {Response} response The fetch response.\n * @returns {Promise<string | JsonApiResponse>} The extracted errors.\n */\n async getErrorsFromResponse(response: Response) {\n const type = response.headers.get(\"content-type\")\n let error: JsonApiResponse | { message: string }\n\n if (type === \"application/json\") {\n error = await response.json()\n\n if (error?.message) {\n return error.message as string\n }\n }\n\n // Construct error from response.\n // Check for type to ensure this is a JSON:API formatted error.\n // See https://jsonapi.org/format/#errors.\n else if (type === \"application/vnd.api+json\") {\n error = (await response.json()) as JsonApiResponse\n\n if (error?.errors?.length) {\n return error.errors\n }\n }\n\n return response.statusText\n }\n}\n\n/**\n * Checks if the provided auth configuration is basic auth.\n *\n * @param {NextDrupalAuth} auth The auth configuration.\n * @returns {boolean} True if the auth configuration is basic auth, false otherwise.\n */\nexport function isBasicAuth(\n auth: NextDrupalAuth\n): auth is NextDrupalAuthUsernamePassword {\n return (\n (auth as NextDrupalAuthUsernamePassword)?.username !== undefined &&\n (auth as NextDrupalAuthUsernamePassword)?.password !== undefined\n )\n}\n\n/**\n * Checks if the provided auth configuration is access token auth.\n *\n * @param {NextDrupalAuth} auth The auth configuration.\n * @returns {boolean} True if the auth configuration is access token auth, false otherwise.\n */\nexport function isAccessTokenAuth(\n auth: NextDrupalAuth\n): auth is NextDrupalAuthAccessToken {\n return (\n (auth as NextDrupalAuthAccessToken)?.access_token !== undefined &&\n (auth as NextDrupalAuthAccessToken)?.token_type !== undefined\n )\n}\n\n/**\n * Checks if the provided auth configuration is client ID and secret auth.\n *\n * @param {NextDrupalAuth} auth The auth configuration.\n * @returns {boolean} True if the auth configuration is client ID and secret auth, false otherwise.\n */\nexport function isClientIdSecretAuth(\n auth: NextDrupalAuth\n): auth is NextDrupalAuthClientIdSecret {\n return (\n (auth as NextDrupalAuthClientIdSecret)?.clientId !== undefined &&\n (auth as NextDrupalAuthClientIdSecret)?.clientSecret !== undefined\n )\n}\n","import type { Logger } from \"./types\"\n\nexport const LOG_MESSAGE_PREFIX = \"[next-drupal][log]:\"\nexport const DEBUG_MESSAGE_PREFIX = \"[next-drupal][debug]:\"\nexport const WARN_MESSAGE_PREFIX = \"[next-drupal][warn]:\"\nexport const ERROR_MESSAGE_PREFIX = \"[next-drupal][error]:\"\n\n// Default logger. Uses console.\nexport const logger: Logger = {\n log(message) {\n console.log(LOG_MESSAGE_PREFIX, message)\n },\n debug(message) {\n console.debug(DEBUG_MESSAGE_PREFIX, message)\n },\n warn(message) {\n console.warn(WARN_MESSAGE_PREFIX, message)\n },\n error(message) {\n console.error(ERROR_MESSAGE_PREFIX, message)\n },\n}\n","import { Jsona } from \"jsona\"\nimport { stringify } from \"qs\"\nimport { JsonApiErrors } from \"./jsonapi-errors\"\nimport { DrupalMenuTree } from \"./menu-tree\"\nimport { NextDrupalBase } from \"./next-drupal-base\"\nimport type {\n BaseUrl,\n DrupalFile,\n DrupalMenuItem,\n DrupalTranslatedPath,\n DrupalView,\n JsonApiCreateFileResourceBody,\n JsonApiCreateResourceBody,\n JsonApiOptions,\n JsonApiParams,\n JsonApiResource,\n JsonApiResourceWithPath,\n JsonApiResponse,\n JsonApiUpdateResourceBody,\n JsonApiWithAuthOption,\n JsonApiWithCacheOptions,\n JsonApiWithNextFetchOptions,\n JsonDeserializer,\n Locale,\n NextDrupalOptions,\n PathPrefix,\n} from \"./types\"\n\nconst DEFAULT_API_PREFIX = \"/jsonapi\"\n\n// See https://jsonapi.org/format/#content-negotiation.\nconst DEFAULT_HEADERS = {\n \"Content-Type\": \"application/vnd.api+json\",\n Accept: \"application/vnd.api+json\",\n}\n\nexport function useJsonaDeserialize() {\n const jsonFormatter = new Jsona()\n return function jsonaDeserialize(\n body: Parameters<JsonDeserializer>[0],\n options: Parameters<JsonDeserializer>[1]\n ) {\n return jsonFormatter.deserialize(body, options)\n }\n}\n\n/**\n * The NextDrupal class extends the NextDrupalBase class and provides methods\n * for interacting with a Drupal backend.\n */\nexport class NextDrupal extends NextDrupalBase {\n cache?: NextDrupalOptions[\"cache\"]\n\n deserializer: JsonDeserializer\n\n throwJsonApiErrors: boolean\n\n useDefaultEndpoints: boolean\n\n /**\n * Instantiates a new NextDrupal.\n *\n * const client = new NextDrupal(baseUrl)\n *\n * @param {baseUrl} baseUrl The baseUrl of your Drupal site. Do not add the /jsonapi suffix.\n * @param {options} options Options for NextDrupal.\n */\n constructor(baseUrl: BaseUrl, options: NextDrupalOptions = {}) {\n super(baseUrl, options)\n\n const {\n apiPrefix = DEFAULT_API_PREFIX,\n cache = null,\n deserializer,\n headers = DEFAULT_HEADERS,\n throwJsonApiErrors = true,\n useDefaultEndpoints = true,\n } = options\n\n this.apiPrefix = apiPrefix\n this.cache = cache\n this.deserializer = deserializer ?? useJsonaDeserialize()\n this.headers = headers\n this.throwJsonApiErrors = !!throwJsonApiErrors\n this.useDefaultEndpoints = !!useDefaultEndpoints\n\n // Do not throw errors in production.\n if (process.env.NODE_ENV === \"production\") {\n this.throwJsonApiErrors = false\n }\n }\n\n /**\n * Creates a new resource of the specified type.\n *\n * @param {string} type The type of the resource. Example: `node--article`, `taxonomy_term--tags`, or `block_content--basic`.\n * @param {JsonApiCreateResourceBody} body The body payload with data.\n * @param {JsonApiOptions & JsonApiWithNextFetchOptions} options Options for the request.\n * @returns {Promise<T>} The created resource.\n * @example\n * Create a node--page resource\n * ```\n * const page = await drupal.createResource(\"node--page\", {\n * data: {\n * attributes: {\n * title: \"Page Title\",\n * body: {\n * value: \"<p>Content of body field</p>\",\n * format: \"full_html\",\n * },\n * },\n * },\n * })\n * ```\n * Create a node--article with a taxonomy term\n * ```\n * const article = await drupal.createResource(\"node--article\", {\n * data: {\n * attributes: {\n * title: \"Title of Article\",\n * body: {\n * value: \"<p>Content of body field</p>\",\n * format: \"full_html\",\n * },\n * },\n * relationships: {\n * field_category: {\n * data: {\n * type: \"taxonomy_term--category\",\n * id: \"28ab9f26-927d-4e33-9510-b59a7ccdafe6\",\n * },\n * },\n * },\n * },\n * })\n * ```\n * Using filters\n * ```\n * const page = await drupal.createResource(\n * \"node--page\",\n * {\n * data: {\n * attributes: {\n * title: \"Page Title\",\n * body: {\n * value: \"<p>Content of body field</p>\",\n * format: \"full_html\",\n * },\n * },\n * },\n * },\n * {\n * params: {\n * \"fields[node--page]\": \"title,path\",\n * },\n * }\n * )\n * ```\n * Using TypeScript with DrupalNode\n * ```\n * import { DrupalNode } from \"next-drupal\"\n * const page = await drupal.createResource<DrupalNode>(\"node--page\", {\n * data: {\n * attributes: {\n * title: \"Page Title\",\n * body: {\n * value: \"<p>Content of body field</p>\",\n * format: \"full_html\",\n * },\n * },\n * },\n * })\n * ```\n */\n async createResource<T extends JsonApiResource>(\n type: string,\n body: JsonApiCreateResourceBody,\n options?: JsonApiOptions & JsonApiWithNextFetchOptions\n ): Promise<T> {\n options = {\n deserialize: true,\n withAuth: true,\n ...options,\n }\n\n const endpoint = await this.buildEndpoint({\n locale:\n options?.locale !== options?.defaultLocale\n ? /* c8 ignore next */ options.locale\n : undefined,\n resourceType: type,\n searchParams: options?.params,\n })\n\n this.debug(`Creating resource of type ${type}.`)\n\n // Add type to body.\n body.data.type = type\n\n const response = await this.fetch(endpoint, {\n method: \"POST\",\n body: JSON.stringify(body),\n withAuth: options.withAuth,\n cache: options.cache,\n })\n\n await this.throwIfJsonErrors(response, \"Error while creating resource: \")\n\n const json = await response.json()\n\n return options.deserialize\n ? this.deserialize(json)\n : /* c8 ignore next */ json\n }\n\n /**\n * Creates a new file resource for the specified media type.\n *\n * @param {string} type The type of the resource. In most cases this is `file--file`.\n * @param {JsonApiCreateFileResourceBody} body The body payload with data.\n * - type: The resource type of the host entity. Example: `media--image`\n * - field: The name of the file field on the host entity. Example: `field_media_image`\n * - filename: The name of the file with extension. Example: `avatar.jpg`\n * - file: The file as a Buffer\n * @param {JsonApiOptions} options Options for the request.\n * @returns {Promise<T>} The created file resource.\n * @example\n * Create a file resource for a media--image entity\n * ```ts\n * const file = await drupal.createFileResource(\"file--file\", {\n * data: {\n * attributes: {\n * type: \"media--image\", // The type of the parent resource\n * field: \"field_media_image\", // The name of the field on the parent resource\n * filename: \"filename.jpg\",\n * file: await fs.readFile(\"/path/to/file.jpg\"),\n * },\n * },\n * })\n * ```\n *\n * You can then use this to create a new media--image with a relationship to the file:\n * ```ts\n * const media = await drupal.createResource<DrupalMedia>(\"media--image\", {\n * data: {\n * attributes: {\n * name: \"Name for the media\",\n * },\n * relationships: {\n * field_media_image: {\n * data: {\n * type: \"file--file\",\n * id: file.id,\n * },\n * },\n * },\n * },\n * })\n * ```\n */\n async createFileResource<T = DrupalFile>(\n type: string,\n body: JsonApiCreateFileResourceBody,\n options?: JsonApiOptions & JsonApiWithNextFetchOptions\n ): Promise<T> {\n options = {\n deserialize: true,\n withAuth: true,\n ...options,\n }\n\n const resourceType = body?.data?.attributes?.type\n\n const endpoint = await this.buildEndpoint({\n locale:\n options?.locale !== options?.defaultLocale ? options.locale : undefined,\n resourceType,\n path: `/${body.data.attributes.field}`,\n searchParams: options?.params,\n })\n\n this.debug(`Creating file resource for media of type ${type}.`)\n\n const response = await this.fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/octet-stream\",\n Accept: \"application/vnd.api+json\",\n \"Content-Disposition\": `file; filename=\"${body.data.attributes.filename}\"`,\n },\n body: body.data.attributes.file,\n withAuth: options.withAuth,\n cache: options.cache,\n })\n\n await this.throwIfJsonErrors(\n response,\n \"Error while creating file resource: \"\n )\n\n const json = await response.json()\n\n return options.deserialize ? this.deserialize(json) : json\n }\n\n /**\n * Updates an existing resource of the specified type.\n *\n * @param {string} type The type of the resource. Example: `node--article`, `taxonomy_term--tags`, or `block_content--basic`.\n * @param {string} uuid The resource id. Example: `a50ffee7-ba94-46c9-9705-f9f8f440db94`.\n * @param {JsonApiUpdateResourceBody} body The body payload with data.\n * @param {JsonApiOptions & JsonApiWithNextFetchOptions} options Options for the request.\n * @returns {Promise<T>} The updated resource.\n * @example\n * Update a node--page resource\n * ```ts\n * const page = await drupal.updateResource(\n * \"node--page\",\n * \"a50ffee7-ba94-46c9-9705-f9f8f440db94\",\n * {\n * data: {\n * attributes: {\n * title: \"Updated Title\",\n * },\n * },\n * }\n * )\n * ```\n *\n * Using TypeScript with DrupalNode for a node entity type\n * ```ts\n * import { DrupalNode } from \"next-drupal\"\n *\n * const page = await drupal.updateResource<DrupalNode>(\n * \"node--page\",\n * \"a50ffee7-ba94-46c9-9705-f9f8f440db94\",\n * {\n * data: {\n * attributes: {\n * title: \"Updated Title\",\n * },\n * },\n * }\n * )\n * ```\n */\n async updateResource<T extends JsonApiResource>(\n type: string,\n uuid: string,\n body: JsonApiUpdateResourceBody,\n options?: JsonApiOptions & JsonApiWithNextFetchOptions\n ): Promise<T> {\n options = {\n deserialize: true,\n withAuth: true,\n ...options,\n }\n\n const endpoint = await this.buildEndpoint({\n locale:\n options?.locale !== options?.defaultLocale\n ? /* c8 ignore next */ options.locale\n : undefined,\n resourceType: type,\n path: `/${uuid}`,\n searchParams: options?.params,\n })\n\n this.debug(`Updating resource of type ${type} with id ${uuid}.`)\n\n // Update body.\n body.data.type = type\n body.data.id = uuid\n\n const response = await this.fetch(endpoint, {\n method: \"PATCH\",\n body: JSON.stringify(body),\n withAuth: options.withAuth,\n cache: options.cache,\n })\n\n await this.throwIfJsonErrors(response, \"Error while updating resource: \")\n\n const json = await response.json()\n\n return options.deserialize\n ? this.deserialize(json)\n : /* c8 ignore next */ json\n }\n\n /**\n * Deletes an existing resource of the specified type.\n *\n * @param {string} type The type of the resource. Example: `node--article`, `taxonomy_term--tags`, or `block_content--basic`.\n * @param {string} uuid The resource id. Example: `a50ffee7-ba94-46c9-9705-f9f8f440db94`.\n * @param {JsonApiOptions & JsonApiWithNextFetchOptions} options Options for the request.\n * @returns {Promise<boolean>} True if the resource was deleted, false otherwise.\n * @example\n * Delete a node--page resource\n * ```ts\n * const isDeleted = await drupal.deleteResource(\n * \"node--page\",\n * \"a50ffee7-ba94-46c9-9705-f9f8f440db94\"\n * )\n * ```\n */\n async deleteResource(\n type: string,\n uuid: string,\n options?: JsonApiOptions & JsonApiWithNextFetchOptions\n ): Promise<boolean> {\n options = {\n withAuth: true,\n params: {},\n ...options,\n }\n\n const endpoint = await this.buildEndpoint({\n locale:\n options?.locale !== options?.defaultLocale\n ? /* c8 ignore next */ options.locale\n : undefined,\n resourceType: type,\n path: `/${uuid}`,\n searchParams: options?.params,\n })\n\n this.debug(`Deleting resource of type ${type} with id ${uuid}.`)\n\n const response = await this.fetch(endpoint, {\n method: \"DELETE\",\n withAuth: options.withAuth,\n cache: options.cache,\n })\n\n await this.throwIfJsonErrors(response, \"Error while deleting resource: \")\n\n return response.status === 204\n }\n\n /**\n * Fetches a resource of the specified type by its UUID.\n *\n * @param {string} type The resource type. Example: `node--article`, `taxonomy_term--tags`, or `block_content--basic`.\n * @param {string} uuid The id of the resource. Example: `15486935-24bf-4be7-b858-a5b2de78d09d`.\n * @param {JsonApiOptions & JsonApiWithCacheOptions & JsonApiWithNextFetchOptions} options Options for the request.\n * @returns {Promise<T>} The fetched resource.\n * @examples\n * Get a page by uuid.\n * ```ts\n * const node = await drupal.getResource(\n * \"node--page\",\n * \"07464e9f-9221-4a4f-b7f2-01389408e6c8\"\n * )\n * ```\n * Get the es translation for a page by uuid.\n * ```ts\n * const node = await drupal.getResource(\n * \"node--page\",\n * \"07464e9f-9221-4a4f-b7f2-01389408e6c8\",\n * {\n * locale: \"es\",\n * defaultLocale: \"en\",\n * }\n * )\n * ```\n * Get the raw JSON:API response.\n * ```ts\n * const { data, meta, links } = await drupal.getResource(\n * \"node--page\",\n * \"07464e9f-9221-4a4f-b7f2-01389408e6c8\",\n * {\n * deserialize: false,\n * }\n * )\n * ```\n * Get a node--article resource using cache.\n * ```ts\n * const id = \"07464e9f-9221-4a4f-b7f2-01389408e6c8\"\n *\n * const article = await drupal.getResource(\"node--article\", id, {\n * withCache: true,\n * cacheKey: `node--article:${id}`,\n * })\n * ```\n * Get a page resource with time-based revalidation.\n * ```ts\n * const node = await drupal.getResource(\n * \"node--page\",\n * \"07464e9f-9221-4a4f-b7f2-01389408e6c8\",\n * { next: { revalidate: 3600 } }\n * )\n * ```\n * Get a page resource with tag-based revalidation.\n * ```ts\n * const {slug} = params;\n * const path = drupal.translatePath(slug)\n *\n * const type = path.jsonapi.resourceName\n * const tag = `${path.entity.type}:${path.entity.id}`\n *\n * const node = await drupal.getResource(path, path.entity.uuid, {\n * params: params.getQueryObject(),\n * tags: [tag]\n * })\n * ```\n * Using DrupalNode for a node entity type.\n * ```ts\n * import { DrupalNode } from \"next-drupal\"\n *\n * const node = await drupal.getResource<DrupalNode>(\n * \"node--page\",\n * \"07464e9f-9221-4a4f-b7f2-01389408e6c8\"\n * )\n * ```\n * Using DrupalTaxonomyTerm for a taxonomy term entity type.\n * ```ts\n * import { DrupalTaxonomyTerm } from \"next-drupal\"\n *\n * const term = await drupal.getResource<DrupalTaxonomyTerm>(\n * \"taxonomy_term--tags\",\n * \"7b47d7cc-9b1b-4867-a909-75dc1d61dfd3\"\n * )\n * ```\n */\n async getResource<T extends JsonApiResource>(\n type: string,\n uuid: string,\n options?: JsonApiOptions &\n JsonApiWithCacheOptions &\n JsonApiWithNextFetchOptions\n ): Promise<T> {\n options = {\n deserialize: true,\n withAuth: this.withAuth,\n withCache: false,\n params: {},\n ...options,\n }\n\n /* c8 ignore next 11 */\n if (options.withCache) {\n const cached = (await this.cache.get(options.cacheKey)) as string\n\n if (cached) {\n this.debug(`Returning cached resource ${type} with id ${uuid}.`)\n\n const json = JSON.parse(cached)\n\n return options.deserialize ? this.deserialize(json) : json\n }\n }\n\n const endpoint = await this.buildEndpoint({\n locale:\n options?.locale !== options?.defaultLocale ? options.locale : undefined,\n resourceType: type,\n path: `/${uuid}`,\n searchParams: options?.params,\n })\n\n this.debug(`Fetching resource ${type} with id ${uuid}.`)\n\n const response = await this.fetch(endpoint, {\n withAuth: options.withAuth,\n next: options.next,\n cache: options.cache,\n })\n\n await this.throwIfJsonErrors(response, \"Error while fetching resource: \")\n\n const json = await response.json()\n\n /* c8 ignore next 3 */\n if (options.withCache) {\n await this.cache.set(options.cacheKey, JSON.stringify(json))\n }\n\n return options.deserialize ? this.deserialize(json) : json\n }\n\n /**\n * Fetches a resource of the specified type by its path.\n *\n * @param {string} path The path of the resource. Example: `/blog/slug-for-article`.\n * @param { { isVersionable?: boolean } & JsonApiOptions & JsonApiWithNextFetchOptions} options Options for the request.\n * - isVersionable: Set to true if you're fetching the revision for a resource. Automatically set to true for node entity types\n * @returns {Promise<T>} The fetched resource.\n * @requires Decoupled Router module\n * @example\n * Get a page by path\n * ```\n * const node = await drupal.getResourceByPath(\"/blog/slug-for-article\")\n * ```\n * Get the raw JSON:API response\n * ```\n * const { data, meta, links } = await drupal.getResourceByPath(\n * \"/blog/slug-for-article\",\n * {\n * deserialize: false,\n * }\n * )\n *```\n * Using DrupalNode for a node entity type\n * ```\n * import { DrupalNode } from \"next-drupal\"\n * const node = await drupal.getResourceByPath<DrupalNode>(\n * \"/blog/slug-for-article\"\n * )\n * ```\n */\n async getResourceByPath<T extends JsonApiResource>(\n path: string,\n options?: {\n isVersionable?: boolean\n } & JsonApiOptions &\n JsonApiWithNextFetchOptions\n ): Promise<T> {\n options = {\n deserialize: true,\n isVersionable: false,\n withAuth: this.withAuth,\n params: {},\n ...options,\n }\n\n if (!path) {\n return null\n }\n\n path = this.addLocalePrefix(path, {\n locale: options.locale,\n defaultLocale: options.defaultLocale,\n })\n\n // If a resourceVersion is provided, assume entity type is versionable.\n if (options.params.resourceVersion) {\n options.isVersionable = true\n }\n\n const { resourceVersion = \"rel:latest-version\", ...params } = options.params\n\n if (options.isVersionable) {\n params.resourceVersion = resourceVersion\n }\n\n const resourceParams = stringify(params)\n\n // We are intentionally not using translatePath here.\n // We want a single request using subrequests.\n const payload = [\n {\n requestId: \"router\",\n action: \"view\",\n uri: `/router/translate-path?path=${path}&_format=json`,\n headers: { Accept: \"application/vnd.api+json\" },\n },\n {\n requestId: \"resolvedResource\",\n action: \"view\",\n uri: `{{router.body@$.jsonapi.individual}}?${resourceParams.toString()}`,\n waitFor: [\"router\"],\n },\n ]\n\n // Handle localized subrequests. It seems like subrequests is not properly\n // setting the jsonapi locale from a translated path.\n // TODO: Confirm we still need this after https://www.drupal.org/i/3111456\n const subrequestsEndpoint = this.addLocalePrefix(\"/subrequests\", {\n locale: options.locale,\n defaultLocale: options.defaultLocale,\n })\n\n const endpoint = this.buildUrl(subrequestsEndpoint, {\n _format: \"json\",\n }).toString()\n\n this.debug(`Fetching resource by path, ${path}.`)\n\n const response = await this.fetch(endpoint, {\n method: \"POST\",\n credentials: \"include\",\n redirect: \"follow\",\n body: JSON.stringify(payload),\n withAuth: options.withAuth,\n next: options.next,\n cache: options.cache,\n })\n\n const errorMessagePrefix = \"Error while fetching resource by path:\"\n\n if (response.status !== 207) {\n const errors = await this.getErrorsFromResponse(response)\n throw new JsonApiErrors(errors, response.status, errorMessagePrefix)\n }\n\n const json = await response.json()\n\n if (!json?.[\"resolvedResource#uri{0}\"]?.body) {\n const status = json?.router?.headers?.status?.[0]\n if (status === 404) {\n return null\n }\n const message =\n (json?.router?.body && JSON.parse(json.router.body)?.message) ||\n \"Unknown error\"\n throw new JsonApiErrors(message, status, errorMessagePrefix)\n }\n\n const data = JSON.parse(json[\"resolvedResource#uri{0}\"]?.body)\n\n if (data.errors) {\n const status = json?.[\"resolvedResource#uri{0}\"]?.headers?.status?.[0]\n this.logOrThrowError(\n new JsonApiErrors(data.errors, status, errorMessagePrefix)\n )\n }\n\n return options.deserialize ? this.deserialize(data) : data\n }\n\n /**\n * Fetches a collection of resources of the specified type.\n *\n * @param {string} type The type of the resources. Example: `node--article` or `user--user`.\n * @param {JsonApiOptions & JsonApiWithNextFetchOptions} options Options for the request.\n * - deserialize: Set to false to return the raw JSON:API response\n * @returns {Promise<T>} The fetched collection of resources.\n * @example\n * Get all articles\n * ```\n * const articles = await drupal.getResourceCollection(\"node--article\")\n * ```\n * Using filters\n * ```\n * const publishedArticles = await drupal.getResourceCollection(\"node--article\", {\n * params: {\n * \"filter[status]\": \"1\",\n * },\n * })\n * ```\n * Get the raw JSON:API response\n * ```\n * const { data, meta, links } = await drupal.getResourceCollection(\"node--page\", {\n * deserialize: false,\n * })\n * ```\n * Using TypeScript with DrupalNode for a node entity type\n * ```\n * import { DrupalNode } from \"next-drupal\"\n * const nodes = await drupal.getResourceCollection<DrupalNode[]>(\"node--article\")\n * ```\n */\n async getResourceCollection<T = JsonApiResource[]>(\n type: string,\n options?: {\n deserialize?: boolean\n } & JsonApiOptions &\n JsonApiWithNextFetchOptions\n ): Promise<T> {\n options = {\n withAuth: this.withAuth,\n deserialize: true,\n ...options,\n }\n\n const endpoint = await this.buildEndpoint({\n locale:\n options?.locale !== options?.defaultLocale ? options.locale : undefined,\n resourceType: type,\n searchParams: options?.params,\n })\n\n this.debug(`Fetching resource collection of type ${type}.`)\n\n const response = await this.fetch(endpoint, {\n withAuth: options.withAuth,\n next: options.next,\n cache: options.cache,\n })\n\n await this.throwIfJsonErrors(\n response,\n \"Error while fetching resource collection: \"\n )\n\n const json = await response.json()\n\n return options.deserialize ? this.deserialize(json) : json\n }\n\n /**\n * Fetches path segments for a collection of resources of the specified types.\n *\n * @param {string | string[]} types The types of the resources.\n * @param {JsonApiOptions & JsonApiWithAuthOption & JsonApiWithNextFetchOptions} options Options for the request.\n * @returns {Promise<{ path: string, type: string, locale: Locale, segments: string[] }[]>} The fetched path segments.\n */\n async getResourceCollectionPathSegments(\n types: string | string[],\n options?: {\n pathPrefix?: PathPrefix\n params?: JsonApiParams\n } & JsonApiWithAuthOption &\n JsonApiWithNextFetchOptions &\n (\n | {\n locales: Locale[]\n defaultLocale: Locale\n }\n | {\n locales?: undefined\n defaultLocale?: never\n }\n )\n ): Promise<\n {\n path: string\n type: string\n locale: Locale\n segments: string[]\n }[]\n > {\n options = {\n withAuth: this.withAuth,\n pathPrefix: \"\",\n params: {},\n ...options,\n }\n\n if (typeof types === \"string\") {\n types = [types]\n }\n\n const paths = await Promise.all(\n types.map(async (type) => {\n // Use sparse fieldset to expand max size.\n // Note we don't need status filter here since this runs non-authenticated (by default).\n const params = {\n [`fields[${type}]`]: \"path\",\n ...options?.params,\n }\n\n const locales = options?.locales?.length ? options.locales : [undefined]\n\n return Promise.all(\n locales.map(async (locale) => {\n let opts: Parameters<NextDrupal[\"getResourceCollection\"]>[1] = {\n params,\n withAuth: options.withAuth,\n next: options.next,\n cache: options.cache,\n }\n if (locale) {\n opts = {\n ...opts,\n deserialize: true,\n locale,\n defaultLocale: options.defaultLocale,\n }\n }\n const resources = await this.getResourceCollection<\n JsonApiResourceWithPath[]\n >(type, opts)\n\n return (\n resources\n .map((resource) => {\n return resource?.path?.alias === this.frontPage\n ? /* c8 ignore next */ \"/\"\n : resource?.path?.alias\n })\n // Remove results with no path aliases.\n .filter(Boolean)\n .map((path) => {\n let segmentPath = path\n\n // Trim the pathPrefix off the front of the path.\n if (\n options.pathPrefix &&\n (segmentPath.startsWith(\n `${options.pathPrefix}/`\n ) /* c8 ignore next */ ||\n segmentPath === options.pathPrefix)\n ) {\n segmentPath = segmentPath.slice(options.pathPrefix.length)\n }\n\n // Convert the trimmed path into an array of path segments.\n const segments = segmentPath.split(\"/\").filter(Boolean)\n\n return {\n path,\n type,\n locale,\n segments,\n }\n })\n )\n })\n )\n })\n )\n\n return paths.flat(2)\n }\n\n /**\n * Translates a path to a DrupalTranslatedPath object.\n *\n * @param {string} path The resource path. Example: `/blog/slug-for-article`.\n * @param {JsonApiWithAuthOption & JsonApiWithNextFetchOptions} options Options for the request.\n * @returns {Promise<DrupalTranslatedPath | null>} The translated path.\n * @requires Decoupled Router module\n * @example\n * Get info about a `/blog/slug-for-article` path\n * ```ts\n * const path = await drupal.translatePath(\"/blog/slug-for-article\")\n * ```\n */\n async translatePath(\n path: string,\n options?: JsonApiWithAuthOption & JsonApiWithNextFetchOptions\n ): Promise<DrupalTranslatedPath | null> {\n options = {\n withAuth: this.withAuth,\n ...options,\n }\n\n const endpoint = this.buildUrl(\"/router/translate-path\", {\n path,\n }).toString()\n\n this.debug(`Fetching translated path, ${path}.`)\n\n const response = await this.fetch(endpoint, {\n withAuth: options.withAuth,\n next: options.next,\n cache: options.cache,\n })\n\n if (response.status === 404) {\n // Do not throw errors here, otherwise Next.js will catch the error and\n // throw a 500. We want a 404.\n return null\n }\n\n await this.throwIfJsonErrors(response)\n\n return await response.json()\n }\n\n /**\n * Fetches the JSON:API index.\n *\n * @param {Locale} locale The locale for the request.\n * @param {JsonApiWithNextFetchOptions} options Options for the request.\n * @returns {Promise<JsonApiResponse>} The JSON:API index.\n */\n async getIndex(\n locale?: Locale,\n options?: JsonApiWithNextFetchOptions\n ): Promise<JsonApiResponse> {\n const endpoint = await this.buildEndpoint({\n locale,\n })\n\n this.debug(`Fetching JSON:API index.`)\n\n const response = await this.fetch(endpoint, {\n // As per https://www.drupal.org/node/2984034 /jsonapi is public.\n withAuth: false,\n next: options?.next,\n cache: options?.cache,\n })\n\n await this.throwIfJsonErrors(\n response,\n `Failed to fetch JSON:API index at ${endpoint}: `\n )\n\n return await response.json()\n }\n\n /**\n * Builds an endpoint URL for the specified parameters.\n *\n * @param {Parameters<NextDrupalBase[\"buildEndpoint\"]>[0] & { resourceType?: string }} params The parameters for the endpoint.\n * @returns {Promise<string>} The built endpoint URL.\n */\n async buildEndpoint({\n locale = \"\",\n resourceType = \"\",\n path = \"\",\n searchParams,\n }: Parameters<NextDrupalBase[\"buildEndpoint\"]>[0] & {\n resourceType?: string\n } = {}): Promise<string> {\n let localeSegment = locale ? `/${locale}` : \"\"\n let apiSegment = this.apiPrefix\n\n // Determine the optional resource part of the endpoint URL.\n let resourceSegment = \"\"\n if (resourceType) {\n if (this.useDefaultEndpoints) {\n const [id, bundle] = resourceType.split(\"--\")\n resourceSegment = `/${id}` + (bundle ? `/${bundle}` : \"\")\n } else {\n resourceSegment = (\n await this.fetchResourceEndpoint(resourceType, locale)\n ).pathname\n // Fetched endpoint URLs already include the apiPrefix and the locale.\n localeSegment = \"\"\n apiSegment = \"\"\n }\n }\n\n if (path && !path.startsWith(\"/\")) {\n path = `/${path}`\n }\n\n return this.buildUrl(\n `${localeSegment}${apiSegment}${resourceSegment}${path}`,\n searchParams\n ).toString()\n }\n\n /**\n * Fetches the endpoint URL for the specified resource type.\n *\n * @param {string} type The type of the resource.\n * @param {Locale} locale The locale for the request.\n * @returns {Promise<URL>} The fetched endpoint URL.\n */\n async fetchResourceEndpoint(type: string, locale?: Locale): Promise<URL> {\n const index = await this.getIndex(locale)\n\n const link = index.links?.[type] as { href: string }\n\n if (!link) {\n throw new Error(`Resource of type '${type}' not found.`)\n }\n\n const url = new URL(link.href)\n\n // TODO: Is this \"fix\" needed any more? Drupal 9.4 and later don't exhibit\n // this behavior.\n // Fix for missing locale in JSON:API index.\n // This fix ensures the locale is included in the resource link.\n /* c8 ignore next 3 */\n if (locale && !url.pathname.startsWith(`/${locale}`)) {\n url.pathname = `/${locale}${url.pathname}`\n }\n\n return url\n }\n\n /**\n * Fetches a menu by its name.\n *\n * @param {string} menuName The name of the menu. Example: `main` or `footer`.\n * @param {JsonApiOptions & JsonApiWithCacheOptions & JsonApiWithNextFetchOptions} options Options for the request.\n * @returns {Promise<{ items: T[], tree: T[] }>} The fetched menu.\n * - items: An array of `DrupalMenuLinkContent`\n * - tree: An array of `DrupalMenuLinkContent` with children nested to match the hierarchy from Drupal\n * @requires JSON:API Menu Items module\n * @example\n * Get the `main` menu\n * ```ts\n * const { menu, items } = await drupal.getMenu(\"main\")\n * ```\n *\n * Get the `main` menu using cache\n * ```ts\n * const menu = await drupal.getMenu(\"main\", {\n * withCache: true,\n * cacheKey: \"menu--main\",\n * })\n * ```\n */\n async getMenu<T = DrupalMenuItem>(\n menuName: string,\n options?: JsonApiOptions &\n JsonApiWithCacheOptions &\n JsonApiWithNextFetchOptions\n ): Promise<{\n items: T[]\n tree: T[]\n }> {\n options = {\n withAuth: this.withAuth,\n deserialize: true,\n params: {},\n withCache: false,\n ...options,\n }\n\n /* c8 ignore next 9 */\n if (options.withCache) {\n const cached = (await this.cache.get(options.cacheKey)) as string\n\n if (cached) {\n this.debug(`Returning cached menu items for ${menuName}.`)\n return JSON.parse(cached)\n }\n }\n\n const endpoint = await this.buildEndpoint({\n locale:\n options?.locale !== options?.defaultLocale ? options.locale : undefined,\n resourceType: \"menu_items\",\n path: menuName,\n searchParams: options.params,\n })\n\n this.debug(`Fetching menu items for ${menuName}.`)\n\n const response = await this.fetch(endpoint, {\n withAuth: options.withAuth,\n next: options.next,\n cache: options.cache,\n })\n\n await this.throwIfJsonErrors(response, \"Error while fetching menu items: \")\n\n const data = await response.json()\n\n const items = options.deserialize\n ? this.deserialize(data)\n : /* c8 ignore next */ data\n\n const tree = new DrupalMenuTree(items)\n\n const menu = {\n items,\n tree: tree.length ? tree : undefined,\n }\n\n /* c8 ignore next 3 */\n if (options.withCache) {\n await this.cache.set(options.cacheKey, JSON.stringify(menu))\n }\n\n return menu\n }\n\n /**\n * Fetches a view by its name.\n *\n * @param {string} name The name of the view and the display id. Example: `articles--promoted`.\n * @param {JsonApiOptions & JsonApiWithNextFetchOptions} options Options for the request.\n * @returns {Promise<DrupalView<T>>} The fetched view.\n * @requires JSON:API Views module\n * @example\n * Get a view named `articles` and display id `promoted`\n * ```ts\n * const view = await drupal.getView(\"articles--promoted\")\n * ```\n *\n * Using sparse fieldsets to only fetch the title and body fields\n * ```ts\n * const view = await drupal.getView(\"articles--promoted\", {\n * params: {\n * fields: {\n * \"node--article\": \"title,body\",\n * },\n * },\n * })\n * ```\n *\n * Using TypeScript with DrupalNode for a node entity type\n * ```ts\n * import { DrupalNode } from \"next-drupal\"\n *\n * const view = await drupal.getView<DrupalNode>(\"articles--promoted\")\n * ```\n */\n async getView<T = JsonApiResource>(\n name: string,\n options?: JsonApiOptions & JsonApiWithNextFetchOptions\n ): Promise<DrupalView<T>> {\n options = {\n withAuth: this.withAuth,\n deserialize: true,\n params: {},\n ...options,\n }\n\n const [viewId, displayId] = name.split(\"--\")\n\n const endpoint = await this.buildEndpoint({\n locale:\n options?.locale !== options?.defaultLocale ? options.locale : undefined,\n path: `/views/${viewId}/${displayId}`,\n searchParams: options.params,\n })\n\n this.debug(`Fetching view, ${viewId}.${displayId}.`)\n\n const response = await this.fetch(endpoint, {\n withAuth: options.withAuth,\n next: options.next,\n cache: options.cache,\n })\n\n await this.throwIfJsonErrors(response, \"Error while fetching view: \")\n\n const data = await response.json()\n\n const results = options.deserialize ? this.deserialize(data) : data\n\n return {\n id: name,\n results,\n meta: data.meta,\n links: data.links,\n }\n }\n\n /**\n * Fetches a search index by its name.\n *\n * @param {string} name The name of the search index.\n * @param {JsonApiOptions & JsonApiWithNextFetchOptions} options Options for the request.\n * @returns {Promise<T>} The fetched search index.\n * @requires JSON:API Search API module\n * @example\n * Get search results from an index named `articles`\n * ```ts\n * const results = await drupal.getSearchIndex(\"articles\")\n * ```\n *\n * Using TypeScript with DrupalNode for a node entity type\n * ```ts\n * import { DrupalNode } from \"next-drupal\"\n *\n * const results = await drupal.getSearchIndex<DrupalNode>(\"articles\")\n * ```\n */\n async getSearchIndex<T = JsonApiResource[]>(\n name: string,\n options?: JsonApiOptions & JsonApiWithNextFetchOptions\n ): Promise<T> {\n options = {\n withAuth: this.withAuth,\n deserialize: true,\n ...options,\n }\n\n const endpoint = await this.buildEndpoint({\n locale:\n options?.locale !== options?.defaultLocale ? options.locale : undefined,\n path: `/index/${name}`,\n searchParams: options.params,\n })\n\n this.debug(`Fetching search index, ${name}.`)\n\n const response = await this.fetch(endpoint, {\n withAuth: options.withAuth,\n next: options.next,\n cache: options.cache,\n })\n\n await this.throwIfJsonErrors(\n response,\n \"Error while fetching search index: \"\n )\n\n const json = await response.json()\n\n return options.deserialize ? this.deserialize(json) : json\n }\n\n /**\n * Deserializes the response body.\n *\n * @param {any} body The response body.\n * @param {any} options Options for deserialization.\n * @returns {any} The deserialized response body.\n * @remarks\n * To provide your own custom deserializer, see the serializer docs.\n * @example\n * ```ts\n * const url = drupal.buildUrl(\"/jsonapi/node/article\", {\n * sort: \"-created\",\n * \"fields[node--article]\": \"title,path\",\n * })\n *\n * const response = await drupal.fetch(url.toString())\n * const json = await response.json()\n *\n * const resource = drupal.deserialize(json)\n * ```\n */\n deserialize(body, options?) {\n if (!body) return null\n\n return this.deserializer(body, options)\n }\n\n /**\n * Logs or throws an error based on the throwJsonApiErrors flag.\n *\n * @param {Error} error The error to log or throw.\n */\n logOrThrowError(error: Error) {\n if (!this.throwJsonApiErrors) {\n this.logger.error(error)\n return\n }\n\n throw error\n }\n}\n","import type { DrupalMenuItem, DrupalMenuItemId } from \"./types\"\n\nexport class DrupalMenuTree<\n T extends {\n id: DrupalMenuItemId\n parent: DrupalMenuItemId\n items?: T[]\n } = DrupalMenuItem,\n> extends Array {\n parentId: DrupalMenuItemId\n depth: number\n\n constructor(\n menuItems: T[],\n parentId: DrupalMenuItemId = \"\",\n depth: number = 1\n ) {\n super()\n\n this.parentId = parentId\n this.depth = depth\n\n if (menuItems?.length) {\n this.build(menuItems, parentId)\n }\n }\n\n build(menuItems: T[], parentId: DrupalMenuItemId) {\n // Find the children of the specified parent.\n const children = menuItems.filter(\n (menuItem) => menuItem?.parent === parentId\n )\n\n // Add each child to this Array.\n for (const menuItem of children) {\n const subtree = new DrupalMenuTree<T>(\n menuItems,\n menuItem.id,\n this.depth + 1\n )\n\n this.push({\n ...menuItem,\n items: subtree.length ? subtree : undefined,\n })\n }\n }\n}\n","import { Jsona } from \"jsona\"\nimport { DRAFT_DATA_COOKIE_NAME } from \"./draft-constants\"\nimport { DrupalMenuTree } from \"./menu-tree\"\nimport { NextDrupal } from \"./next-drupal\"\nimport { isClientIdSecretAuth } from \"./next-drupal-base\"\nimport type {\n BaseUrl,\n DrupalClientOptions,\n DrupalMenuItem,\n DrupalMenuItemId,\n DrupalPathAlias,\n DrupalTranslatedPath,\n JsonApiOptions,\n JsonApiParams,\n JsonApiResource,\n JsonApiResourceWithPath,\n JsonApiWithAuthOption,\n JsonDeserializer,\n Locale,\n PathPrefix,\n} from \"./types\"\nimport type {\n GetStaticPathsContext,\n GetStaticPathsResult,\n GetStaticPropsContext,\n NextApiRequest,\n NextApiResponse,\n} from \"next\"\n\n/**\n * The NextDrupalPages class extends the NextDrupal class and provides methods\n * for interacting with a Drupal backend in the context of Next.js pages.\n */\nexport class NextDrupalPages extends NextDrupal {\n private serializer: DrupalClientOptions[\"serializer\"]\n\n /**\n * Instantiates a new NextDrupalPages.\n *\n * const client = new NextDrupalPages(baseUrl)\n *\n * @param {baseUrl} baseUrl The baseUrl of your Drupal site. Do not add the /jsonapi suffix.\n * @param {options} options Options for the client. See Experiment_DrupalClientOptions.\n */\n constructor(baseUrl: BaseUrl, options: DrupalClientOptions = {}) {\n super(baseUrl, options)\n\n const {\n serializer = new Jsona(),\n useDefaultResourceTypeEntry = false,\n useDefaultEndpoints = null,\n } = options\n\n if (useDefaultEndpoints === null) {\n this.useDefaultEndpoints = !!useDefaultResourceTypeEntry\n }\n\n this.serializer = serializer\n\n this.deserializer = (\n body: Parameters<JsonDeserializer>[0],\n options: Parameters<JsonDeserializer>[1]\n ) => this.serializer.deserialize(body, options)\n }\n\n /**\n * Get the JSON:API entry for a resource type.\n *\n * @param {string} resourceType The resource type. Example: `node--article`.\n * @param {Locale} locale Optional. The locale to fetch the index. Example: `es` or `fr`.\n * @returns {Promise<string>} The entry point URL.\n * @remarks\n * By default, when retrieving resources in `getResource` or `getResourceCollection`,\n * the `DrupalClient` make a request to Drupal to fetch the JSON:API resource entry.\n *\n * Example: if you provide `node--article`, `DrupalClient` will make a request to\n * `http://example.com/jsonapi/node/article`.\n *\n * If you would like to infer the entry from the resource type, use the useDefaultResourceTypeEntry option:\n * ```ts\n * const drupal = new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, {\n * useDefaultResourceTypeEntry: true,\n * })\n * ```\n * @example\n * ```ts\n * // https://example.com/jsonapi/node/article\n * const url = await drupal.getEntryForResourceType(`node--article`)\n * ```\n */\n async getEntryForResourceType(\n resourceType: string,\n locale?: Locale\n ): Promise<string> {\n return this.buildEndpoint({\n locale,\n resourceType,\n })\n }\n\n /* c8 ignore next 3 */\n buildMenuTree(links: DrupalMenuItem[], parent: DrupalMenuItemId = \"\") {\n return new DrupalMenuTree<DrupalMenuItem>(links, parent)\n }\n\n /**\n * Gets a resource from the context.\n *\n * @param {string | DrupalTranslatedPath} input Either a resource type (e.g. \"node--article\") or a translated path from translatePath().\n * @param {GetStaticPropsContext} context The Next.js context from getStaticProps.\n * @param {Object} options Options for the request.\n * @param {PathPrefix} [options.pathPrefix] The path prefix to use for the request (defaults to \"/\").\n * @param {boolean} [options.isVersionable] Whether the resource is versionable (defaults to false for all entity types except nodes).\n * @returns {Promise<T>} The fetched resource.\n * @remarks\n * The localized resource will be fetched based on the `locale` and `defaultLocale` values from `context`.\n *\n * If you pass in a `DrupalTranslatedPath` for input, `getResourceFromContext` will take the `type` and `id` from the path and make a `getResource` call to Drupal:\n * ```ts\n * export async function getStaticProps(context) {\n * const path = await drupal.translatePathFromContext(context)\n *\n * const node = await drupal.getResourceFromContext(path, context)\n *\n * return {\n * props: {\n * node,\n * },\n * }\n * }\n * ```\n *\n * If you pass in a `string` input, such as `node--article`, `getResourceFromContext` will make a subrequest call to Drupal to translate the path and then fetch the resource.\n * You will need both the [Subrequests](https://drupal.org/project/subrequests) and [Decoupled Router](https://drupal.org/project/decoupled_router) modules:\n * ```ts\n * export async function getStaticProps(context) {\n * const node = await drupal.getResourceFromContext(\"node--article\", context)\n *\n * return {\n * props: {\n * node,\n * },\n * }\n * }\n * ```\n * @examples\n * Fetch a resource from context.\n * ```ts title=pages/[[...slug]].tsx\n * export async function getStaticProps(context) {\n * const node = await drupal.getResourceFromContext(\"node--page\", context)\n *\n * return {\n * props: {\n * node,\n * },\n * }\n * }\n * ```\n * Fetch a resource from context in a sub directory.\n * ```ts title=pages/articles/[[...slug]].tsx\n * export async function getStaticProps(context) {\n * const node = await drupal.getResourceFromContext(\"node--page\", context, {\n * pathPrefix: \"/articles\",\n * })\n *\n * return {\n * props: {\n * node,\n * },\n * }\n * }\n * ```\n * Using DrupalNode type:\n * ```ts\n * import { DrupalNode } from \"next-drupal\"\n *\n * const node = await drupal.getResourceFromContext<DrupalNode>(\n * \"node--page\",\n * context\n * )\n * ```\n * Using DrupalTaxonomyTerm type:\n * ```ts\n * import { DrupalTaxonomyTerm } from \"next-drupal\"\n *\n * const term = await drupal.getResourceFromContext<DrupalTaxonomyTerm>(\n * \"taxonomy_term--tags\",\n * context\n * )\n * ```\n * @see {@link https://next-drupal.org/docs/typescript} for more built-in types.\n */\n async getResourceFromContext<T extends JsonApiResource>(\n input: string | DrupalTranslatedPath,\n context: GetStaticPropsContext,\n options?: {\n pathPrefix?: PathPrefix\n isVersionable?: boolean\n } & JsonApiOptions\n ): Promise<T> {\n const type = typeof input === \"string\" ? input : input.jsonapi.resourceName\n\n const previewData = context.previewData as {\n resourceVersion?: string\n }\n\n options = {\n deserialize: true,\n pathPrefix: \"/\",\n withAuth: this.getAuthFromContextAndOptions(context, options),\n params: {},\n ...options,\n }\n\n const _options = {\n deserialize: options.deserialize,\n isVersionable: options.isVersionable,\n locale: context.locale,\n defaultLocale: context.defaultLocale,\n withAuth: options?.withAuth,\n params: options?.params,\n }\n\n // Check if resource is versionable.\n // Add support for revisions for node by default.\n const isVersionable = options.isVersionable || /^node--/.test(type)\n\n // If the resource is versionable and no resourceVersion is supplied via params.\n // Use the resourceVersion from previewData or fallback to the latest version.\n if (\n isVersionable &&\n typeof options.params.resourceVersion === \"undefined\"\n ) {\n options.params.resourceVersion =\n previewData?.resourceVersion || \"rel:latest-version\"\n }\n\n if (typeof input !== \"string\") {\n // Fix for subrequests and translation.\n // TODO: Confirm if we still need this after https://www.drupal.org/i/3111456.\n // Given an entity at /example with no translation.\n // When we try to translate /es/example, decoupled router will properly\n // translate to the untranslated version and set the locale to es.\n // However a subrequests to /es/subrequests for decoupled router will fail.\n /* c8 ignore next 3 */\n if (context.locale && input.entity.langcode !== context.locale) {\n context.locale = input.entity.langcode\n }\n\n // Given we already have the path info, we can skip subrequests and just make a simple\n // request to the Drupal site to get the entity.\n if (input.entity?.uuid) {\n return await this.getResource<T>(type, input.entity.uuid, _options)\n }\n }\n\n const path = this.getPathFromContext(context, {\n pathPrefix: options?.pathPrefix,\n })\n\n const resource = await this.getResourceByPath<T>(path, _options)\n\n // If no locale is passed, skip entity if not default_langcode.\n // This happens because decoupled_router will still translate the path\n // to a resource.\n // TODO: Figure out if we want this behavior.\n // For now this causes a bug where a non-i18n sites builds (ISR) pages for\n // localized pages.\n // if (!context.locale && !resource?.default_langcode) {\n // return null\n // }\n\n return resource\n }\n\n /**\n * Gets a collection of resources from the context.\n *\n * @param {string} type The type of the resources. Example: `node--article` or `user--user`.\n * @param {GetStaticPropsContext} context The static props context from getStaticProps or getServerSideProps.\n * @param {Object} options Options for the request.\n * - deserialize: Set to false to return the raw JSON:API response\n * @returns {Promise<T>} The fetched collection of resources.\n * @remarks\n * The localized resources will be fetched based on the `locale` and `defaultLocale` values from `context`.\n * @example\n * Get all articles from context\n * ```\n * export async function getStaticProps(context) {\n * const articles = await drupal.getResourceCollectionFromContext(\n * \"node--article\",\n * context\n * )\n *\n * return {\n * props: {\n * articles,\n * },\n * }\n * }\n * ```\n * Using TypeScript with DrupalNode for a node entity type\n * ```\n * import { DrupalNode } from \"next-drupal\"\n * const nodes = await drupal.getResourceCollectionFromContext<DrupalNode[]>(\n * \"node--article\",\n * context\n * )\n * ```\n */\n async getResourceCollectionFromContext<T = JsonApiResource[]>(\n type: string,\n context: GetStaticPropsContext,\n options?: {\n deserialize?: boolean\n } & JsonApiOptions\n ): Promise<T> {\n options = {\n deserialize: true,\n ...options,\n }\n\n return await this.getResourceCollection<T>(type, {\n ...options,\n locale: context.locale,\n defaultLocale: context.defaultLocale,\n withAuth: this.getAuthFromContextAndOptions(context, options),\n })\n }\n\n /**\n * Gets a search index from the context.\n *\n * @param {string} name The name of the search index.\n * @param {GetStaticPropsContext} context The static props context.\n * @param {Object} options Options for the request.\n * @returns {Promise<T>} The fetched search index.\n */\n async getSearchIndexFromContext<T = JsonApiResource[]>(\n name: string,\n context: GetStaticPropsContext,\n options?: JsonApiOptions\n ): Promise<T> {\n return await this.getSearchIndex<T>(name, {\n ...options,\n locale: context.locale,\n defaultLocale: context.defaultLocale,\n })\n }\n\n /**\n * Translates a path from the context.\n *\n * @param {GetStaticPropsContext} context The context from `getStaticProps` or `getServerSideProps`.\n * @param {Object} options Options for the request.\n * @returns {Promise<DrupalTranslatedPath | null>} The translated path.\n * @requires Decoupled Router module\n * @example\n * Get info about a path from `getStaticProps` context\n * ```ts\n * export async function getStaticProps(context) {\n * const path = await drupal.translatePathFromContext(context)\n * }\n * ```\n */\n async translatePathFromContext(\n context: GetStaticPropsContext,\n options?: {\n pathPrefix?: PathPrefix\n } & JsonApiWithAuthOption\n ): Promise<DrupalTranslatedPath | null> {\n options = {\n pathPrefix: \"/\",\n ...options,\n }\n const path = this.getPathFromContext(context, {\n pathPrefix: options.pathPrefix,\n })\n\n return await this.translatePath(path, {\n withAuth: this.getAuthFromContextAndOptions(context, options),\n })\n }\n\n /**\n * Return the path (slug) from getStaticProps or getServerSideProps context.\n *\n * @param {GetStaticPropsContext} context The context from `getStaticProps` or `getServerSideProps`.\n * @param {Object} options Options for the request.\n * @returns {string} The constructed path.\n * @example\n * Get the path (slug) from `getStaticProps` context\n * ```ts\n * export async function getStaticProps(context) {\n * const slug = await drupal.getPathFromContext(context)\n * }\n * ```\n */\n getPathFromContext(\n context: GetStaticPropsContext,\n options?: {\n pathPrefix?: PathPrefix\n }\n ) {\n return this.constructPathFromSegment(context.params?.slug, {\n locale: context.locale,\n defaultLocale: context.defaultLocale,\n pathPrefix: options?.pathPrefix,\n })\n }\n\n getPathsFromContext = this.getStaticPathsFromContext\n\n /**\n * Gets static paths from the context.\n *\n * @param {string | string[]} types The resource types. Example: `node--article` or `[\"taxonomy_term--tags\", \"user--user\"]`.\n * @param {GetStaticPathsContext} context The context from `getStaticPaths`.\n * @param {object} options Options for the request.\n * @returns {Promise<GetStaticPathsResult<{ slug: string[] }>[\"paths\"]>} The static paths.\n * @example\n * Return static paths for `node--page` resources\n * ```ts\n * export async function getStaticPaths(context) {\n * return {\n * paths: await drupal.getStaticPathsFromContext(\"node--page\", context),\n * fallback: \"blocking\",\n * }\n * }\n * ```\n *\n * Return static paths for `node--page` and `node--article` resources\n * ```ts\n * export async function getStaticPaths(context) {\n * return {\n * paths: await drupal.getStaticPathsFromContext(\n * [\"node--page\", \"node--article\"],\n * context\n * ),\n * fallback: \"blocking\",\n * }\n * }\n * ```\n */\n async getStaticPathsFromContext(\n types: string | string[],\n context: GetStaticPathsContext,\n options?: {\n params?: JsonApiParams\n pathPrefix?: PathPrefix\n } & JsonApiWithAuthOption\n ): Promise<GetStaticPathsResult<{ slug: string[] }>[\"paths\"]> {\n options = {\n withAuth: this.withAuth,\n pathPrefix: \"/\",\n params: {},\n ...options,\n }\n\n if (typeof types === \"string\") {\n types = [types]\n }\n\n const paths = await Promise.all(\n types.map(async (type) => {\n // Use sparse fieldset to expand max size.\n // Note we don't need status filter here since this runs non-authenticated (by default).\n const params = {\n [`fields[${type}]`]: \"path\",\n ...options?.params,\n }\n\n // Handle localized path aliases\n if (!context.locales?.length) {\n const resources = await this.getResourceCollection<\n JsonApiResourceWithPath[]\n >(type, {\n params,\n withAuth: options.withAuth,\n })\n\n return this.buildStaticPathsFromResources(resources, {\n pathPrefix: options.pathPrefix,\n })\n }\n\n const paths = await Promise.all(\n context.locales.map(async (locale) => {\n const resources = await this.getResourceCollection<\n JsonApiResourceWithPath[]\n >(type, {\n deserialize: true,\n locale,\n defaultLocale: context.defaultLocale,\n params,\n withAuth: options.withAuth,\n })\n\n return this.buildStaticPathsFromResources(resources, {\n locale,\n pathPrefix: options.pathPrefix,\n })\n })\n )\n\n return paths.flat()\n })\n )\n\n return paths.flat()\n }\n\n /**\n * Builds static paths from resources.\n *\n * @param {Object[]} resources The resources.\n * @param {Object} options Options for the request.\n * @returns {Object[]} The built static paths.\n */\n buildStaticPathsFromResources(\n resources: {\n path: DrupalPathAlias\n }[],\n options?: {\n pathPrefix?: PathPrefix\n locale?: Locale\n }\n ) {\n const paths = resources\n ?.flatMap((resource) => {\n return resource?.path?.alias === this.frontPage\n ? \"/\"\n : resource?.path?.alias\n })\n .filter(Boolean)\n\n return paths?.length\n ? this.buildStaticPathsParamsFromPaths(paths, options)\n : []\n }\n\n /**\n * Builds static paths parameters from paths.\n *\n * @param {string[]} paths The paths.\n * @param {Object} options Options for the request.\n * @returns {Object[]} The built static paths parameters.\n */\n buildStaticPathsParamsFromPaths(\n paths: string[],\n options?: { pathPrefix?: PathPrefix; locale?: Locale }\n ) {\n return paths.flatMap((_path) => {\n _path = _path.replace(/^\\/|\\/$/g, \"\")\n\n // Remove pathPrefix.\n if (options?.pathPrefix && options.pathPrefix !== \"/\") {\n // Remove leading slash from pathPrefix.\n const pathPrefix = options.pathPrefix.replace(/^\\//, \"\")\n\n _path = _path.replace(`${pathPrefix}/`, \"\")\n }\n\n const path = {\n params: {\n slug: _path.split(\"/\"),\n },\n }\n\n if (options?.locale) {\n path[\"locale\"] = options.locale\n }\n\n return path\n })\n }\n\n /**\n * Handle preview mode for resources.\n *\n * @param {NextApiRequest} request The `request` from an API route.\n * @param {NextApiResponse} response The `response` from an API route.\n * @param {Object} options Options for the request.\n * @returns {Promise<void>}\n * @remarks\n * The `preview` method should be called in an API route.\n * Remember to set a `previewSecret` on the client.\n * ```ts\n * // lib/drupal.ts\n * export const drupal = new DrupalClient(\n * process.env.NEXT_PUBLIC_DRUPAL_BASE_URL,\n * {\n * previewSecret: process.env.DRUPAL_PREVIEW_SECRET,\n * }\n * )\n * ```\n * @example\n * ```ts\n * // pages/api/preview.ts\n * import { drupal } from \"lib/drupal\"\n *\n * export default async function handler(req, res) {\n * return await drupal.preview(req, res)\n * }\n * ```\n */\n async preview(\n request: NextApiRequest,\n response: NextApiResponse,\n options?: Parameters<NextApiResponse[\"setDraftMode\"]>[0]\n ) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { path, resourceVersion, plugin, secret, scope, ...draftData } =\n request.query\n const useDraftMode = options?.enable\n\n try {\n // Always clear preview data to handle different scopes.\n response.clearPreviewData()\n\n // Validate the preview url.\n const result = await this.validateDraftUrl(\n new URL(request.url, `http://${request.headers.host}`).searchParams\n )\n\n const validationPayload = await result.json()\n const previewData = {\n resourceVersion,\n plugin,\n ...validationPayload,\n }\n\n if (!result.ok) {\n this.debug(`Draft url validation error: ${validationPayload.message}`)\n response.statusCode = result.status\n return response.json(validationPayload)\n }\n\n // Optionally turn on draft mode.\n if (useDraftMode) {\n response.setDraftMode(options)\n }\n\n // Turns on preview mode and adds preview data to Next.js' static context.\n response.setPreviewData(previewData)\n\n // Fix issue with cookie.\n // See https://github.com/vercel/next.js/discussions/32238.\n // See https://github.com/vercel/next.js/blob/d895a50abbc8f91726daa2d7ebc22c58f58aabbb/packages/next/server/api-utils/node.ts#L504.\n const cookies = (response.getHeader(\"Set-Cookie\") as string[]).map(\n (cookie) => cookie.replace(\"SameSite=Lax\", \"SameSite=None; Secure\")\n )\n if (useDraftMode) {\n // Adds preview data for use in app router pages.\n cookies.push(\n `${DRAFT_DATA_COOKIE_NAME}=${encodeURIComponent(\n JSON.stringify({ path, resourceVersion, ...draftData })\n )}; Path=/; HttpOnly; SameSite=None; Secure`\n )\n }\n response.setHeader(\"Set-Cookie\", cookies)\n\n // We can safely redirect to the path since this has been validated on the\n // server.\n response.writeHead(307, { Location: path })\n\n this.debug(`${useDraftMode ? \"Draft\" : \"Preview\"} mode enabled.`)\n\n return response.end()\n } catch (error) {\n this.debug(`Preview failed: ${error.message}`)\n return response.status(422).end()\n }\n }\n\n /**\n * Disables preview mode.\n *\n * @param {NextApiRequest} request The API request.\n * @param {NextApiResponse} response The API response.\n */\n async previewDisable(request: NextApiRequest, response: NextApiResponse) {\n // Disable both preview and draft modes.\n response.clearPreviewData()\n response.setDraftMode({ enable: false })\n\n // Delete the draft data cookie.\n const cookies = response.getHeader(\"Set-Cookie\") as string[]\n cookies.push(\n `${DRAFT_DATA_COOKIE_NAME}=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; SameSite=None; Secure`\n )\n response.setHeader(\"Set-Cookie\", cookies)\n\n response.writeHead(307, { Location: \"/\" })\n response.end()\n }\n\n /**\n * Gets the authentication configuration from the context and options.\n *\n * @param {GetStaticPropsContext} context The static props context.\n * @param {JsonApiWithAuthOption} options Options for the request.\n * @returns {NextDrupalAuth} The authentication configuration.\n */\n getAuthFromContextAndOptions(\n context: GetStaticPropsContext,\n options: JsonApiWithAuthOption\n ) {\n // If not in preview or withAuth is provided, use that.\n if (!context.preview) {\n // If we have provided an auth, use that.\n if (typeof options?.withAuth !== \"undefined\") {\n return options.withAuth\n }\n\n // Otherwise we fall back to the global auth.\n return this.withAuth\n }\n\n // If no plugin is provided, return.\n const plugin = context.previewData?.[\"plugin\"]\n if (!plugin) {\n return null\n }\n\n let withAuth = this.auth\n\n if (plugin === \"simple_oauth\") {\n // If we are using a client id and secret auth, pass the scope.\n if (isClientIdSecretAuth(withAuth) && context.previewData?.[\"scope\"]) {\n withAuth = {\n ...withAuth,\n scope: context.previewData?.[\"scope\"],\n }\n }\n }\n\n if (plugin === \"jwt\") {\n const accessToken = context.previewData?.[\"access_token\"]\n\n if (accessToken) {\n return `Bearer ${accessToken}`\n }\n }\n\n return withAuth\n }\n}\n","import NodeCache from \"node-cache\"\n\nexport const cache = new NodeCache()\n","import { cache } from \"./get-cache\"\nimport type { AccessToken } from \"../types\"\n\nconst CACHE_KEY = \"NEXT_DRUPAL_ACCESS_TOKEN\"\n\n/** @deprecated */\nexport async function getAccessToken(): Promise<AccessToken> {\n if (!process.env.DRUPAL_CLIENT_ID || !process.env.DRUPAL_CLIENT_SECRET) {\n return null\n }\n\n const cached = cache.get<AccessToken>(CACHE_KEY)\n if (cached?.access_token) {\n return cached\n }\n\n const basic = Buffer.from(\n `${process.env.DRUPAL_CLIENT_ID}:${process.env.DRUPAL_CLIENT_SECRET}`\n ).toString(\"base64\")\n\n const response = await fetch(\n `${process.env.NEXT_PUBLIC_DRUPAL_BASE_URL}/oauth/token`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Basic ${basic}`,\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: `grant_type=client_credentials`,\n }\n )\n\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n\n const result: AccessToken = await response.json()\n\n cache.set(CACHE_KEY, result, result.expires_in)\n\n return result\n}\n","import { Jsona } from \"jsona\"\nimport { stringify } from \"qs\"\nimport { getAccessToken } from \"./get-access-token\"\nimport type { GetStaticPropsContext } from \"next\"\nimport type { AccessToken, Locale } from \"../types\"\n\nconst JSONAPI_PREFIX = process.env.DRUPAL_JSONAPI_PREFIX || \"/jsonapi\"\n\nconst dataFormatter = new Jsona()\n\nexport function deserialize(body, options?) {\n if (!body) return null\n\n return dataFormatter.deserialize(body, options)\n}\n\nexport async function getJsonApiPathForResourceType(\n type: string,\n locale?: Locale\n) {\n const index = await getJsonApiIndex(locale)\n\n return index?.links[type]?.href\n}\n\nexport async function getJsonApiIndex(\n locale?: Locale,\n options?: {\n accessToken?: AccessToken\n }\n): Promise<{\n links: {\n [type: string]: {\n href: string\n }\n }\n}> {\n const url = buildUrl(\n locale ? `/${locale}${JSONAPI_PREFIX}` : `${JSONAPI_PREFIX}`\n )\n\n // As per https://www.drupal.org/node/2984034 /jsonapi is public.\n // We only call buildHeaders if accessToken or locale is explicitly set.\n // This is for rare cases where /jsonapi might be protected.\n const response = await fetch(url.toString(), {\n headers:\n locale || options\n ? await buildHeaders(options)\n : {\n \"Content-Type\": \"application/json\",\n },\n })\n\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n\n return await response.json()\n}\n\nexport function buildUrl(\n path: string,\n params?: string | Record<string, string> | URLSearchParams\n): URL {\n const url = new URL(\n path.charAt(0) === \"/\"\n ? `${process.env.NEXT_PUBLIC_DRUPAL_BASE_URL}${path}`\n : path\n )\n\n if (params) {\n // Use instead URLSearchParams for nested params.\n url.search = stringify(params)\n }\n\n return url\n}\n\nexport async function buildHeaders({\n accessToken,\n headers = {\n \"Content-Type\": \"application/json\",\n },\n}: {\n accessToken?: AccessToken\n headers?: RequestInit[\"headers\"]\n} = {}): Promise<RequestInit[\"headers\"]> {\n // This allows an access_token (preferrably long-lived) to be set directly on the env.\n // This reduces the number of OAuth call to the Drupal server.\n // Intentionally marked as unstable for now.\n if (process.env.UNSTABLE_DRUPAL_ACCESS_TOKEN) {\n headers[\"Authorization\"] =\n `Bearer ${process.env.UNSTABLE_DRUPAL_ACCESS_TOKEN}`\n\n return headers\n }\n\n const token = accessToken || (await getAccessToken())\n if (token) {\n headers[\"Authorization\"] = `Bearer ${token.access_token}`\n }\n\n return headers\n}\n\nexport function getPathFromContext(\n context: GetStaticPropsContext,\n prefix = \"\"\n) {\n let { slug } = context.params\n\n slug = Array.isArray(slug)\n ? slug.map((s) => encodeURIComponent(s)).join(\"/\")\n : slug\n\n // Handle locale.\n if (context.locale && context.locale !== context.defaultLocale) {\n slug = `/${context.locale}/${slug}`\n }\n\n return !slug\n ? process.env.DRUPAL_FRONT_PAGE\n : prefix\n ? `${prefix}/${slug}`\n : slug\n}\n\nexport function syncDrupalPreviewRoutes(path) {\n if (window && window.top !== window.self) {\n window.parent.postMessage(\n { type: \"NEXT_DRUPAL_ROUTE_SYNC\", path },\n process.env.NEXT_PUBLIC_DRUPAL_BASE_URL\n )\n }\n}\n","import { buildHeaders, buildUrl, deserialize } from \"./utils\"\nimport type { AccessToken, DrupalMenuItem } from \"../types\"\nimport type { JsonApiWithLocaleOptions } from \"../types/deprecated\"\n\nexport async function getMenu<T extends DrupalMenuItem>(\n name: string,\n options?: {\n deserialize?: boolean\n accessToken?: AccessToken\n } & JsonApiWithLocaleOptions\n): Promise<{\n items: T[]\n tree: T[]\n}> {\n options = {\n deserialize: true,\n ...options,\n }\n\n const localePrefix =\n options?.locale && options.locale !== options.defaultLocale\n ? `/${options.locale}`\n : \"\"\n\n const url = buildUrl(`${localePrefix}/jsonapi/menu_items/${name}`)\n\n const response = await fetch(url.toString(), {\n headers: await buildHeaders(options),\n })\n\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n\n const data = await response.json()\n\n const items = options.deserialize ? deserialize(data) : data\n\n const { items: tree } = buildMenuTree(items)\n\n return {\n items,\n tree,\n }\n}\n\nfunction buildMenuTree(\n links: DrupalMenuItem[],\n parent: DrupalMenuItem[\"id\"] = \"\"\n) {\n if (!links?.length) {\n return {\n items: [],\n }\n }\n\n const children = links.filter((link) => link.parent === parent)\n\n return children.length\n ? {\n items: children.map((link) => ({\n ...link,\n ...buildMenuTree(links, link.id),\n })),\n }\n : {}\n}\n","import {\n buildHeaders,\n buildUrl,\n deserialize,\n getJsonApiPathForResourceType,\n} from \"./utils\"\nimport type { GetStaticPropsContext } from \"next\"\nimport type { AccessToken, JsonApiParams, JsonApiResource } from \"../types\"\nimport type { JsonApiWithLocaleOptions } from \"../types/deprecated\"\n\nexport async function getResourceCollection<T = JsonApiResource[]>(\n type: string,\n options?: {\n deserialize?: boolean\n accessToken?: AccessToken\n } & JsonApiWithLocaleOptions\n): Promise<T> {\n options = {\n deserialize: true,\n ...options,\n }\n\n const apiPath = await getJsonApiPathForResourceType(\n type,\n options?.locale !== options?.defaultLocale ? options.locale : undefined\n )\n\n if (!apiPath) {\n throw new Error(`Error: resource of type ${type} not found.`)\n }\n\n const url = buildUrl(apiPath, {\n ...options?.params,\n })\n\n const response = await fetch(url.toString(), {\n headers: await buildHeaders(options),\n })\n\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n\n const json = await response.json()\n\n return options.deserialize ? deserialize(json) : json\n}\n\nexport async function getResourceCollectionFromContext<T = JsonApiResource[]>(\n type: string,\n context: GetStaticPropsContext,\n options?: {\n deserialize?: boolean\n params?: JsonApiParams\n }\n): Promise<T> {\n options = {\n deserialize: true,\n ...options,\n }\n\n // // Filter out unpublished entities.\n // if (!context.preview) {\n // options.params = {\n // \"filter[status]\": \"1\",\n // ...options.params,\n // }\n // }\n\n return await getResourceCollection<T>(type, {\n ...options,\n locale: context.locale,\n defaultLocale: context.defaultLocale,\n })\n}\n","import { getResourceCollection } from \"./get-resource-collection\"\nimport type { GetStaticPathsContext, GetStaticPathsResult } from \"next\"\nimport type { AccessToken, JsonApiParams, Locale } from \"../types\"\n\nexport async function getPathsFromContext(\n types: string | string[],\n context: GetStaticPathsContext,\n options: {\n params?: JsonApiParams\n accessToken?: AccessToken\n } = {}\n): Promise<GetStaticPathsResult[\"paths\"]> {\n if (typeof types === \"string\") {\n types = [types]\n }\n\n const paths = await Promise.all(\n types.map(async (type) => {\n // Use sparse fieldset to expand max size.\n options.params = {\n [`fields[${type}]`]: \"path\",\n ...options?.params,\n }\n\n // const paths = await Promise.all(\n // context.locales.map(async (locale) => {\n // const resources = await getResourceCollection(type, {\n // deserialize: true,\n // locale,\n // defaultLocale: context.defaultLocale,\n // ...options,\n // })\n\n // return buildPathsFromResources(resources, locale)\n // })\n // )\n\n // return paths.flat()\n\n // Handle localized path aliases\n if (!context.locales?.length) {\n const resources = await getResourceCollection(type, {\n deserialize: true,\n ...options,\n })\n\n return buildPathsFromResources(resources)\n }\n\n const paths = await Promise.all(\n context.locales.map(async (locale) => {\n const resources = await getResourceCollection(type, {\n deserialize: true,\n locale,\n defaultLocale: context.defaultLocale,\n ...options,\n })\n\n return buildPathsFromResources(resources, locale)\n })\n )\n\n return paths.flat()\n })\n )\n\n return paths.flat()\n}\n\nfunction buildPathsFromResources(resources, locale?: Locale) {\n return resources?.flatMap((resource) => {\n const slug =\n resource?.path?.alias === process.env.DRUPAL_FRONT_PAGE\n ? \"/\"\n : resource?.path?.alias\n\n const path = {\n params: {\n slug: `${slug?.replace(/^\\/|\\/$/g, \"\")}`.split(\"/\"),\n },\n }\n\n if (locale) {\n path[\"locale\"] = locale\n }\n\n return path\n })\n}\n","import { stringify } from \"qs\"\nimport {\n buildHeaders,\n buildUrl,\n deserialize,\n getJsonApiPathForResourceType,\n getPathFromContext,\n} from \"./utils\"\nimport type { GetStaticPropsContext } from \"next\"\nimport type { AccessToken, JsonApiParams, JsonApiResource } from \"../types\"\nimport type { JsonApiWithLocaleOptions } from \"../types/deprecated\"\n\nexport async function getResourceFromContext<T extends JsonApiResource>(\n type: string,\n context: GetStaticPropsContext,\n options?: {\n prefix?: string\n deserialize?: boolean\n params?: JsonApiParams\n accessToken?: AccessToken\n isVersionable?: boolean\n }\n): Promise<T> {\n options = {\n deserialize: true,\n // Add support for revisions for node by default.\n // TODO: Make this required before stable?\n isVersionable: /^node--/.test(type),\n ...options,\n }\n\n const path = getPathFromContext(context, options?.prefix)\n\n // Filter out unpublished entities.\n // if (!context.preview) {\n // options.params = {\n // \"filter[status]\": \"1\",\n // ...options?.params,\n // }\n // }\n\n const previewData = context.previewData as { resourceVersion?: string }\n\n const resource = await getResourceByPath<T>(path, {\n deserialize: options.deserialize,\n isVersionable: options.isVersionable,\n locale: context.locale,\n defaultLocale: context.defaultLocale,\n params: {\n resourceVersion: previewData?.resourceVersion,\n ...options?.params,\n },\n })\n\n // If no locale is passed, skip entity if not default_langcode.\n // This happens because decoupled_router will still translate the path\n // to a resource.\n // TODO: Figure out if we want this behavior.\n // For now this causes a bug where a non-i18n sites builds (ISR) pages for\n // localized pages.\n // if (!context.locale && !resource?.default_langcode) {\n // return null\n // }\n\n return resource\n}\n\nexport async function getResourceByPath<T extends JsonApiResource>(\n path: string,\n options?: {\n accessToken?: AccessToken\n deserialize?: boolean\n isVersionable?: boolean\n } & JsonApiWithLocaleOptions\n): Promise<T> {\n options = {\n deserialize: true,\n isVersionable: false,\n params: {},\n ...options,\n }\n\n if (!path) {\n return null\n }\n\n if (\n options.locale &&\n options.defaultLocale &&\n path.indexOf(options.locale) !== 1\n ) {\n path = path === \"/\" ? path : path.replace(/^\\/+/, \"\")\n path = getPathFromContext({\n params: { slug: [path] },\n locale: options.locale,\n defaultLocale: options.defaultLocale,\n })\n }\n\n const { resourceVersion = \"rel:latest-version\", ...params } = options.params\n\n if (options.isVersionable) {\n params.resourceVersion = resourceVersion\n }\n\n const resourceParams = stringify(params)\n\n const payload = [\n {\n requestId: \"router\",\n action: \"view\",\n uri: `/router/translate-path?path=${path}&_format=json`,\n headers: { Accept: \"application/vnd.api+json\" },\n },\n {\n requestId: \"resolvedResource\",\n action: \"view\",\n uri: `{{router.body@$.jsonapi.individual}}?${resourceParams.toString()}`,\n waitFor: [\"router\"],\n },\n ]\n\n // Localized subrequests.\n // I was hoping we would not need this but it seems like subrequests is not properly\n // setting the jsonapi locale from a translated path.\n let subrequestsPath = \"/subrequests\"\n if (\n options.locale &&\n options.defaultLocale &&\n options.locale !== options.defaultLocale\n ) {\n subrequestsPath = `/${options.locale}/subrequests`\n }\n\n const url = buildUrl(subrequestsPath, {\n _format: \"json\",\n })\n\n const response = await fetch(url.toString(), {\n method: \"POST\",\n credentials: \"include\",\n headers: await buildHeaders(options),\n redirect: \"follow\",\n body: JSON.stringify(payload),\n })\n\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n\n const json = await response.json()\n\n if (!json[\"resolvedResource#uri{0}\"]) {\n return null\n }\n\n const data = JSON.parse(json[\"resolvedResource#uri{0}\"]?.body)\n\n if (data.errors) {\n throw new Error(data.errors[0].detail)\n }\n\n return options.deserialize ? deserialize(data) : data\n}\n\nexport async function getResource<T extends JsonApiResource>(\n type: string,\n uuid: string,\n options?: {\n accessToken?: AccessToken\n deserialize?: boolean\n } & JsonApiWithLocaleOptions\n): Promise<T> {\n options = {\n deserialize: true,\n params: {},\n ...options,\n }\n\n const apiPath = await getJsonApiPathForResourceType(\n type,\n options?.locale !== options?.defaultLocale ? options.locale : undefined\n )\n\n if (!apiPath) {\n throw new Error(`Error: resource of type ${type} not found.`)\n }\n\n const url = buildUrl(`${apiPath}/${uuid}`, {\n ...options?.params,\n })\n\n const response = await fetch(url.toString(), {\n headers: await buildHeaders(options),\n })\n\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n\n const json = await response.json()\n\n return options.deserialize ? deserialize(json) : json\n}\n","import { getResourceByPath } from \"./get-resource\"\nimport type { NextApiRequest, NextApiResponse } from \"next\"\nimport type { JsonApiWithLocaleOptions } from \"../types/deprecated\"\n\ninterface PreviewOptions {\n errorMessages?: {\n secret?: string\n slug?: string\n }\n}\n\nexport function DrupalPreview(options?: PreviewOptions) {\n return (request, response) => PreviewHandler(request, response, options)\n}\n\nexport async function PreviewHandler(\n request?: NextApiRequest,\n response?: NextApiResponse,\n options?: PreviewOptions\n) {\n const { path, resourceVersion, secret, locale, defaultLocale } = request.query\n\n if (secret !== process.env.DRUPAL_PREVIEW_SECRET) {\n return response.status(401).json({\n message: options?.errorMessages.secret || \"Invalid preview secret.\",\n })\n }\n\n if (!path) {\n return response\n .status(401)\n .end({ message: options?.errorMessages.slug || \"Invalid slug.\" })\n }\n\n let _options: GetResourcePreviewUrlOptions = {\n isVersionable: typeof resourceVersion !== \"undefined\",\n }\n if (locale && defaultLocale) {\n _options = {\n ..._options,\n locale: locale as string,\n defaultLocale: defaultLocale as string,\n }\n }\n\n const url = await getResourcePreviewUrl(path as string, _options)\n\n if (!url) {\n response\n .status(404)\n .end({ message: options?.errorMessages.slug || \"Invalid slug\" })\n }\n\n response.setPreviewData({\n resourceVersion,\n })\n\n response.writeHead(307, { Location: url })\n\n return response.end()\n}\n\ntype GetResourcePreviewUrlOptions = JsonApiWithLocaleOptions & {\n isVersionable?: boolean\n}\n\nexport async function getResourcePreviewUrl(\n slug: string,\n options?: GetResourcePreviewUrlOptions\n) {\n const entity = await getResourceByPath(slug, options)\n\n if (!entity) {\n return null\n }\n\n if (!entity?.path) {\n throw new Error(\n `Error: the path attribute is missing for entity type ${entity.type}`\n )\n }\n\n return entity?.default_langcode\n ? entity.path.alias\n : `/${entity.path.langcode}${entity.path.alias}`\n}\n","import { buildHeaders, buildUrl, getPathFromContext } from \"./utils\"\nimport type { GetStaticPropsContext } from \"next\"\nimport type { AccessToken, DrupalTranslatedPath } from \"../types\"\n\nexport async function translatePath(\n path: string,\n options?: {\n accessToken?: AccessToken\n }\n): Promise<DrupalTranslatedPath> {\n const url = buildUrl(\"/router/translate-path\", {\n path,\n })\n\n const response = await fetch(url.toString(), {\n headers: await buildHeaders(options),\n })\n\n if (!response.ok) {\n return null\n }\n\n const json = await response.json()\n\n return json\n}\n\nexport async function translatePathFromContext(\n context: GetStaticPropsContext,\n options?: {\n accessToken?: AccessToken\n prefix?: string\n }\n): Promise<DrupalTranslatedPath> {\n options = {\n prefix: \"\",\n ...options,\n }\n const path = getPathFromContext(context, options.prefix)\n\n const response = await translatePath(path, {\n accessToken: options.accessToken,\n })\n\n return response\n}\n","import { translatePathFromContext } from \"./translate-path\"\nimport type { GetStaticPropsContext } from \"next\"\nimport type { AccessToken } from \"../types\"\n\nexport async function getResourceTypeFromContext(\n context: GetStaticPropsContext,\n options?: {\n accessToken?: AccessToken\n prefix?: string\n }\n): Promise<string> {\n try {\n const response = await translatePathFromContext(context, options)\n\n return response.jsonapi.resourceName\n } catch (error) {\n return null\n }\n}\n","import { buildHeaders, buildUrl, deserialize } from \"./utils\"\nimport type { GetStaticPropsContext } from \"next\"\nimport type { AccessToken, JsonApiResource } from \"../types\"\nimport type { JsonApiWithLocaleOptions } from \"../types/deprecated\"\n\nexport async function getSearchIndex<T = JsonApiResource[]>(\n name: string,\n options?: {\n deserialize?: boolean\n accessToken?: AccessToken\n } & JsonApiWithLocaleOptions\n): Promise<T> {\n options = {\n deserialize: true,\n ...options,\n }\n\n const localePrefix =\n options?.locale && options.locale !== options.defaultLocale\n ? `/${options.locale}`\n : \"\"\n\n const url = buildUrl(`${localePrefix}/jsonapi/index/${name}`, options.params)\n\n const response = await fetch(url.toString(), {\n headers: await buildHeaders(options),\n })\n\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n\n const json = await response.json()\n\n return options.deserialize ? deserialize(json) : json\n}\n\nexport async function getSearchIndexFromContext<T = JsonApiResource[]>(\n name: string,\n context: GetStaticPropsContext,\n options?: {\n deserialize?: boolean\n accessToken?: AccessToken\n } & JsonApiWithLocaleOptions\n): Promise<T> {\n options = {\n deserialize: true,\n ...options,\n }\n\n return await getSearchIndex<T>(name, {\n ...options,\n locale: context.locale,\n defaultLocale: context.defaultLocale,\n })\n}\n","import { buildHeaders, buildUrl, deserialize } from \"./utils\"\nimport type { AccessToken } from \"../types\"\nimport type { JsonApiWithLocaleOptions } from \"../types/deprecated\"\n\nexport async function getView<T>(\n name: string,\n options?: {\n deserialize?: boolean\n accessToken?: AccessToken\n } & JsonApiWithLocaleOptions\n): Promise<{\n results: T\n /* eslint-disable @typescript-eslint/no-explicit-any */\n meta: Record<string, any>\n links: {\n [key in \"next\" | \"prev\" | \"self\"]?: {\n href: \"string\"\n }\n }\n}> {\n options = {\n deserialize: true,\n ...options,\n }\n\n const localePrefix =\n options?.locale && options.locale !== options.defaultLocale\n ? `/${options.locale}`\n : \"\"\n\n const [viewId, displayId] = name.split(\"--\")\n\n const url = buildUrl(\n `${localePrefix}/jsonapi/views/${viewId}/${displayId}`,\n options.params\n )\n\n const response = await fetch(url.toString(), {\n headers: await buildHeaders(options),\n })\n\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n\n const data = await response.json()\n\n const results = options.deserialize ? deserialize(data) : data\n\n return {\n results,\n meta: data.meta,\n links: data.links,\n }\n}\n","import { NextDrupalPages } from \"./next-drupal-pages\"\nexport const DrupalClient = NextDrupalPages\n\nexport * from \"./deprecated/get-access-token\"\nexport * from \"./deprecated/get-menu\"\nexport * from \"./deprecated/get-paths\"\nexport * from \"./deprecated/get-resource-collection\"\nexport * from \"./deprecated/preview\"\nexport * from \"./deprecated/get-resource-type\"\nexport * from \"./deprecated/get-resource\"\nexport * from \"./deprecated/get-search-index\"\nexport * from \"./deprecated/get-view\"\nexport * from \"./deprecated/translate-path\"\nexport {\n deserialize,\n buildUrl,\n getJsonApiIndex,\n getJsonApiPathForResourceType,\n syncDrupalPreviewRoutes,\n} from \"./deprecated/utils\"\n\nexport type * from \"./types/deprecated\"\n"],"mappings":"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","names":["logger","import_qs","DEFAULT_API_PREFIX","DEFAULT_HEADERS","cache","json","import_jsona","options","paths","NodeCache","import_jsona","import_qs","paths","import_qs"]}