UNPKG

@prismicio/client

Version:

The official JavaScript + TypeScript client library for Prismic

1 lines 75.9 kB
{"version":3,"file":"Client.cjs","sources":["../../src/Client.ts"],"sourcesContent":["import { appendFilters } from \"./lib/appendFilters\"\nimport { castThunk } from \"./lib/castThunk\"\nimport { devMsg } from \"./lib/devMsg\"\nimport { everyTagFilter } from \"./lib/everyTagFilter\"\nimport { findMasterRef } from \"./lib/findMasterRef\"\nimport { findRefByID } from \"./lib/findRefByID\"\nimport { findRefByLabel } from \"./lib/findRefByLabel\"\nimport { getPreviewCookie } from \"./lib/getPreviewCookie\"\nimport { minifyGraphQLQuery } from \"./lib/minifyGraphQLQuery\"\nimport { someTagsFilter } from \"./lib/someTagsFilter\"\nimport { throttledLog } from \"./lib/throttledLog\"\nimport { typeFilter } from \"./lib/typeFilter\"\n\nimport type { Query } from \"./types/api/query\"\nimport type { Ref } from \"./types/api/ref\"\nimport type { Form, Repository } from \"./types/api/repository\"\nimport type { PrismicDocument } from \"./types/value/document\"\n\nimport { ForbiddenError } from \"./errors/ForbiddenError\"\nimport { NotFoundError } from \"./errors/NotFoundError\"\nimport { ParsingError } from \"./errors/ParsingError\"\nimport { PreviewTokenExpiredError } from \"./errors/PreviewTokenExpired\"\nimport { PrismicError } from \"./errors/PrismicError\"\nimport { RefExpiredError } from \"./errors/RefExpiredError\"\nimport { RefNotFoundError } from \"./errors/RefNotFoundError\"\nimport { RepositoryNotFoundError } from \"./errors/RepositoryNotFoundError\"\n\nimport type { LinkResolverFunction } from \"./helpers/asLink\"\nimport { asLink } from \"./helpers/asLink\"\n\nimport {\n\ttype AbortSignalLike,\n\tBaseClient,\n\ttype BaseClientConfig,\n\ttype FetchParams,\n\ttype HttpRequestLike,\n} from \"./BaseClient\"\nimport type { BuildQueryURLArgs } from \"./buildQueryURL\"\nimport { buildQueryURL } from \"./buildQueryURL\"\nimport { filter } from \"./filter\"\nimport { getRepositoryEndpoint } from \"./getRepositoryEndpoint\"\nimport { getRepositoryName } from \"./getRepositoryName\"\nimport { isRepositoryEndpoint } from \"./isRepositoryEndpoint\"\n\n/**\n * The largest page size allowed by the Prismic REST API V2. This value is used\n * to minimize the number of requests required to query content.\n */\nconst MAX_PAGE_SIZE = 100\n\n/**\n * The number of milliseconds in which repository metadata is considered valid.\n * A ref can be invalidated quickly depending on how frequently content is\n * updated in the Prismic repository. As such, repository's metadata can only be\n * considered valid for a short amount of time.\n */\nexport const REPOSITORY_CACHE_TTL = 5000\n\n/**\n * The number of milliseconds in which a multi-page `getAll` (e.g. `getAll`,\n * `getAllByType`, `getAllByTag`) will wait between individual page requests.\n *\n * This is done to ensure API performance is sustainable and reduces the chance\n * of a failed API request due to overloading.\n */\nexport const GET_ALL_QUERY_DELAY = 500\n\n/**\n * The default number of milliseconds to wait before retrying a rate-limited\n * `fetch()` request (429 response code). The default value is only used if the\n * response does not include a `retry-after` header.\n *\n * The API allows up to 200 requests per second.\n */\nconst DEFAULT_RETRY_AFTER_MS = 1000\n\n/**\n * The maximum number of attempts to retry a query with an invalid ref. We allow\n * multiple attempts since each attempt may use a different (and possibly\n * invalid) ref. Capping the number of attempts prevents infinite loops.\n */\nconst MAX_INVALID_REF_RETRY_ATTEMPTS = 3\n\n/**\n * Extracts one or more Prismic document types that match a given Prismic\n * document type. If no matches are found, no extraction is performed and the\n * union of all provided Prismic document types are returned.\n *\n * @typeParam TDocuments - Prismic document types from which to extract.\n * @typeParam TDocumentType - Type(s) to match `TDocuments` against.\n */\ntype ExtractDocumentType<\n\tTDocuments extends PrismicDocument,\n\tTDocumentType extends TDocuments[\"type\"],\n> =\n\tExtract<TDocuments, { type: TDocumentType }> extends never\n\t\t? TDocuments\n\t\t: Extract<TDocuments, { type: TDocumentType }>\n\n/**\n * Modes for client ref management.\n */\nenum RefStateMode {\n\t/**\n\t * Use the repository's master ref.\n\t */\n\tMaster = \"Master\",\n\n\t/**\n\t * Use a given Release identified by its ID.\n\t */\n\tReleaseID = \"ReleaseID\",\n\n\t/**\n\t * Use a given Release identified by its label.\n\t */\n\tReleaseLabel = \"ReleaseLabel\",\n\n\t/**\n\t * Use a given ref.\n\t */\n\tManual = \"Manual\",\n}\n\n/**\n * An object containing stateful information about a client's ref strategy.\n */\ntype RefState = {\n\t/**\n\t * Determines if automatic preview support is enabled.\n\t */\n\tautoPreviewsEnabled: boolean\n\n\t/**\n\t * An optional HTTP server request object used during previews if automatic\n\t * previews are enabled.\n\t */\n\thttpRequest?: HttpRequestLike\n} & (\n\t| {\n\t\t\tmode: RefStateMode.Master\n\t }\n\t| {\n\t\t\tmode: RefStateMode.ReleaseID\n\t\t\treleaseID: string\n\t }\n\t| {\n\t\t\tmode: RefStateMode.ReleaseLabel\n\t\t\treleaseLabel: string\n\t }\n\t| {\n\t\t\tmode: RefStateMode.Manual\n\t\t\tref: RefStringOrThunk\n\t }\n)\n\n/**\n * A ref or a function that returns a ref. If a static ref is known, one can be\n * given. If the ref must be fetched on-demand, a function can be provided. This\n * function can optionally be asynchronous.\n */\ntype RefStringOrThunk =\n\t| string\n\t| (() => string | undefined | Promise<string | undefined>)\n\n/**\n * Configuration for clients that determine how content is queried.\n */\nexport type ClientConfig = {\n\t/**\n\t * The full Rest API V2 endpoint for the repository. This is only helpful if\n\t * you're using Prismic behind a proxy which we do not recommend.\n\t *\n\t * @defaultValue `getRepositoryEndpoint(repositoryNameOrEndpoint)`\n\t */\n\tdocumentAPIEndpoint?: string\n\n\t/**\n\t * The secure token for accessing the Prismic repository. This is only\n\t * required if the repository is set to private.\n\t */\n\taccessToken?: string\n\n\t/**\n\t * A string representing a version of the Prismic repository's content. This\n\t * may point to the latest version (called the \"master ref\"), or a preview\n\t * with draft content.\n\t */\n\tref?: RefStringOrThunk\n\n\t/**\n\t * A list of route resolver objects that define how a document's `url`\n\t * property is resolved.\n\t *\n\t * {@link https://prismic.io/docs/route-resolver}\n\t */\n\troutes?: NonNullable<BuildQueryURLArgs[\"routes\"]>\n\n\t/**\n\t * The `brokenRoute` option allows you to define the route populated in the\n\t * `url` property for broken link or content relationship fields. A broken\n\t * link is a link or content relationship field whose linked document has been\n\t * unpublished or deleted.\n\t *\n\t * {@link https://prismic.io/docs/route-resolver}\n\t */\n\tbrokenRoute?: NonNullable<BuildQueryURLArgs[\"brokenRoute\"]>\n\n\t/**\n\t * Default parameters that will be sent with each query. These parameters can\n\t * be overridden on each query if needed.\n\t */\n\tdefaultParams?: Omit<\n\t\tBuildQueryURLArgs,\n\t\t\"ref\" | \"integrationFieldsRef\" | \"accessToken\" | \"routes\" | \"brokenRoute\"\n\t>\n} & BaseClientConfig\n\n/**\n * Parameters specific to client methods that fetch all documents. These methods\n * start with `getAll` (for example, `getAllByType`).\n */\ntype GetAllParams = {\n\t/**\n\t * Limit the number of documents queried. If a number is not provided, there\n\t * will be no limit and all matching documents will be returned.\n\t */\n\tlimit?: number\n}\n\n/**\n * Arguments to determine how the URL for a preview session is resolved.\n */\ntype ResolvePreviewArgs<LinkResolverReturnType> = {\n\t/**\n\t * A function that maps a Prismic document to a URL within your app.\n\t */\n\tlinkResolver?: LinkResolverFunction<LinkResolverReturnType>\n\n\t/**\n\t * A fallback URL if the link resolver does not return a value.\n\t */\n\tdefaultURL: string\n\n\t/**\n\t * The preview token (also known as a ref) that will be used to query preview\n\t * content from the Prismic repository.\n\t */\n\tpreviewToken?: string\n\n\t/**\n\t * The previewed document that will be used to determine the destination URL.\n\t */\n\tdocumentID?: string\n}\n\n/**\n * A client that allows querying content from a Prismic repository.\n *\n * If used in an environment where a global `fetch` function is unavailable,\n * such as Node.js, the `fetch` option must be provided as part of the `options`\n * parameter.\n *\n * @typeParam TDocuments - Document types that are registered for the Prismic\n * repository. Query methods will automatically be typed based on this type.\n */\nexport class Client<\n\tTDocuments extends PrismicDocument = PrismicDocument,\n> extends BaseClient {\n\t#repositoryName: string | undefined\n\n\t/**\n\t * The Prismic repository's name.\n\t */\n\tset repositoryName(value: string) {\n\t\tthis.#repositoryName = value\n\t}\n\n\t/**\n\t * The Prismic repository's name.\n\t */\n\tget repositoryName(): string {\n\t\tif (!this.#repositoryName) {\n\t\t\tthrow new PrismicError(\n\t\t\t\t`A repository name is required for this method but one could not be inferred from the provided API endpoint (\\`${this.documentAPIEndpoint}\\`). To fix this error, provide a repository name when creating the client. For more details, see ${devMsg(\"prefer-repository-name\")}`,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t)\n\t\t}\n\n\t\treturn this.#repositoryName\n\t}\n\n\t/**\n\t * The Prismic REST API V2 endpoint for the repository (use\n\t * `prismic.getRepositoryEndpoint` for the default endpoint).\n\t */\n\tdocumentAPIEndpoint: string\n\n\t/**\n\t * The Prismic REST API V2 endpoint for the repository (use\n\t * `prismic.getRepositoryEndpoint` for the default endpoint).\n\t *\n\t * @deprecated Use `documentAPIEndpoint` instead.\n\t */\n\t// TODO: Remove in v8.\n\tset endpoint(value: string) {\n\t\tthis.documentAPIEndpoint = value\n\t}\n\n\t/**\n\t * The Prismic REST API V2 endpoint for the repository (use\n\t * `prismic.getRepositoryEndpoint` for the default endpoint).\n\t *\n\t * @deprecated Use `documentAPIEndpoint` instead.\n\t */\n\t// TODO: Remove in v8.\n\tget endpoint(): string {\n\t\treturn this.documentAPIEndpoint\n\t}\n\n\t/**\n\t * The secure token for accessing the API (only needed if your repository is\n\t * set to private).\n\t *\n\t * {@link https://user-guides.prismic.io/en/articles/1036153-generating-an-access-token}\n\t */\n\taccessToken?: string\n\n\t/**\n\t * A list of route resolver objects that define how a document's `url` field\n\t * is resolved.\n\t *\n\t * {@link https://prismic.io/docs/route-resolver}\n\t */\n\troutes?: NonNullable<BuildQueryURLArgs[\"routes\"]>\n\n\t/**\n\t * The `brokenRoute` option allows you to define the route populated in the\n\t * `url` property for broken link or content relationship fields. A broken\n\t * link is a link or content relationship field whose linked document has been\n\t * unpublished or deleted.\n\t *\n\t * {@link https://prismic.io/docs/route-resolver}\n\t */\n\tbrokenRoute?: NonNullable<BuildQueryURLArgs[\"brokenRoute\"]>\n\n\t/**\n\t * Default parameters that will be sent with each query. These parameters can\n\t * be overridden on each query if needed.\n\t */\n\tdefaultParams?: Omit<\n\t\tBuildQueryURLArgs,\n\t\t\"ref\" | \"integrationFieldsRef\" | \"accessToken\" | \"routes\"\n\t>\n\n\t/**\n\t * The client's ref mode state. This determines which ref is used during\n\t * queries.\n\t */\n\tprivate refState: RefState = {\n\t\tmode: RefStateMode.Master,\n\t\tautoPreviewsEnabled: true,\n\t}\n\n\t/**\n\t * Cached repository value.\n\t */\n\tprivate cachedRepository: Repository | undefined\n\n\t/**\n\t * Timestamp at which the cached repository data is considered stale.\n\t */\n\tprivate cachedRepositoryExpiration = 0\n\n\t/**\n\t * Creates a Prismic client that can be used to query a repository.\n\t *\n\t * If used in an environment where a global `fetch` function is unavailable,\n\t * such as in some Node.js versions, the `fetch` option must be provided as\n\t * part of the `options` parameter.\n\t *\n\t * @param repositoryNameOrEndpoint - The Prismic repository name or full Rest\n\t * API V2 endpoint for the repository.\n\t * @param options - Configuration that determines how content will be queried\n\t * from the Prismic repository.\n\t *\n\t * @returns A client that can query content from the repository.\n\t */\n\tconstructor(repositoryNameOrEndpoint: string, options: ClientConfig = {}) {\n\t\tsuper(options)\n\n\t\tif (\n\t\t\t(options.documentAPIEndpoint ||\n\t\t\t\tisRepositoryEndpoint(repositoryNameOrEndpoint)) &&\n\t\t\tprocess.env.NODE_ENV === \"development\"\n\t\t) {\n\t\t\tconst documentAPIEndpoint =\n\t\t\t\toptions.documentAPIEndpoint || repositoryNameOrEndpoint\n\n\t\t\t// Matches non-API v2 `.prismic.io` endpoints, see: https://regex101.com/r/xRsavu/1\n\t\t\tif (/\\.prismic\\.io\\/(?!api\\/v2\\/?)/i.test(documentAPIEndpoint)) {\n\t\t\t\tthrow new PrismicError(\n\t\t\t\t\t\"@prismicio/client only supports Prismic Rest API V2. Please provide only the repository name to the first createClient() parameter or use the getRepositoryEndpoint() helper to generate a valid Rest API V2 endpoint URL.\",\n\t\t\t\t\tundefined,\n\t\t\t\t\tundefined,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst hostname = new URL(documentAPIEndpoint).hostname.toLowerCase()\n\n\t\t\t// Matches non-.cdn `.prismic.io` endpoints\n\t\t\tif (\n\t\t\t\thostname.endsWith(\".prismic.io\") &&\n\t\t\t\t!hostname.endsWith(\".cdn.prismic.io\")\n\t\t\t) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[@prismicio/client] The client was created with a non-CDN endpoint. Convert it to the CDN endpoint for better performance. For more details, see ${devMsg(\"endpoint-must-use-cdn\")}`,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// Warn if the user provided both a repository endpoint and an `documentAPIEndpoint` and they are different\n\t\t\tif (\n\t\t\t\toptions.documentAPIEndpoint &&\n\t\t\t\tisRepositoryEndpoint(repositoryNameOrEndpoint) &&\n\t\t\t\trepositoryNameOrEndpoint !== options.documentAPIEndpoint\n\t\t\t) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[@prismicio/client] Multiple incompatible endpoints were provided. Create the client using a repository name to prevent this error. For more details, see ${devMsg(\"prefer-repository-name\")}`,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tif (isRepositoryEndpoint(repositoryNameOrEndpoint)) {\n\t\t\tthis.documentAPIEndpoint = repositoryNameOrEndpoint\n\t\t\ttry {\n\t\t\t\tthis.repositoryName = getRepositoryName(repositoryNameOrEndpoint)\n\t\t\t} catch (error) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[@prismicio/client] A repository name could not be inferred from the provided endpoint (\\`${repositoryNameOrEndpoint}\\`). Some methods will be disabled. Create the client using a repository name to prevent this warning. For more details, see ${devMsg(\"prefer-repository-name\")}`,\n\t\t\t\t)\n\t\t\t}\n\t\t} else {\n\t\t\tthis.documentAPIEndpoint =\n\t\t\t\toptions.documentAPIEndpoint ||\n\t\t\t\tgetRepositoryEndpoint(repositoryNameOrEndpoint)\n\t\t\tthis.repositoryName = repositoryNameOrEndpoint\n\t\t}\n\n\t\tthis.accessToken = options.accessToken\n\t\tthis.routes = options.routes\n\t\tthis.brokenRoute = options.brokenRoute\n\t\tthis.defaultParams = options.defaultParams\n\n\t\tif (options.ref) {\n\t\t\tthis.queryContentFromRef(options.ref)\n\t\t}\n\n\t\tthis.graphQLFetch = this.graphQLFetch.bind(this)\n\t}\n\n\t/**\n\t * Enables the client to automatically query content from a preview session if\n\t * one is active in browser environments. This is enabled by default in the\n\t * browser.\n\t *\n\t * For server environments, use `enableAutoPreviewsFromReq`.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * client.enableAutoPreviews()\n\t * ```\n\t *\n\t * @see enableAutoPreviewsFromReq\n\t */\n\tenableAutoPreviews(): void {\n\t\tthis.refState.autoPreviewsEnabled = true\n\t}\n\n\t/**\n\t * Enables the client to automatically query content from a preview session if\n\t * one is active in server environments. This is disabled by default on the\n\t * server.\n\t *\n\t * For browser environments, use `enableAutoPreviews`.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * // In an express app\n\t * app.get(\"/\", function (req, res) {\n\t * \tclient.enableAutoPreviewsFromReq(req)\n\t * })\n\t * ```\n\t *\n\t * @param req - An HTTP server request object containing the request's\n\t * cookies.\n\t */\n\tenableAutoPreviewsFromReq<R extends HttpRequestLike>(req: R): void {\n\t\tthis.refState.httpRequest = req\n\t\tthis.refState.autoPreviewsEnabled = true\n\t}\n\n\t/**\n\t * Disables the client from automatically querying content from a preview\n\t * session if one is active.\n\t *\n\t * Automatic preview content querying is enabled by default unless this method\n\t * is called.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * client.disableAutoPreviews()\n\t * ```\n\t */\n\tdisableAutoPreviews(): void {\n\t\tthis.refState.autoPreviewsEnabled = false\n\t}\n\n\t/**\n\t * Queries content from the Prismic repository.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.get()\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param params - Parameters to filter, sort, and paginate results.\n\t *\n\t * @returns A paginated response containing the result of the query.\n\t */\n\tasync get<TDocument extends TDocuments>(\n\t\tparams?: Partial<BuildQueryURLArgs> & FetchParams,\n\t): Promise<Query<TDocument>> {\n\t\tconst { data } = await this._get<TDocument>(params)\n\n\t\treturn data\n\t}\n\n\t/**\n\t * Queries content from the Prismic repository and returns only the first\n\t * result, if any.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const document = await client.getFirst()\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of the Prismic document returned.\n\t *\n\t * @param params - Parameters to filter, sort, and paginate results.\n\t *\n\t * @returns The first result of the query, if any.\n\t */\n\tasync getFirst<TDocument extends TDocuments>(\n\t\tparams?: Partial<BuildQueryURLArgs> & FetchParams,\n\t): Promise<TDocument> {\n\t\tconst actualParams = { ...params }\n\t\tif (!(params && params.page) && !params?.pageSize) {\n\t\t\tactualParams.pageSize = this.defaultParams?.pageSize ?? 1\n\t\t}\n\t\tconst { data, url } = await this._get<TDocument>(actualParams)\n\n\t\tconst firstResult = data.results[0]\n\n\t\tif (firstResult) {\n\t\t\treturn firstResult\n\t\t}\n\n\t\tthrow new NotFoundError(\"No documents were returned\", url, undefined)\n\t}\n\n\t/**\n\t * **IMPORTANT**: Avoid using `dangerouslyGetAll` as it may be slower and\n\t * require more resources than other methods. Prefer using other methods that\n\t * filter by filters such as `getAllByType`.\n\t *\n\t * Queries content from the Prismic repository and returns all matching\n\t * content. If no filters are provided, all documents will be fetched.\n\t *\n\t * This method may make multiple network requests to query all matching\n\t * content.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.dangerouslyGetAll()\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param params - Parameters to filter, sort, and paginate results.\n\t *\n\t * @returns A list of documents matching the query.\n\t */\n\tasync dangerouslyGetAll<TDocument extends TDocuments>(\n\t\tparams: Partial<Omit<BuildQueryURLArgs, \"page\">> &\n\t\t\tGetAllParams &\n\t\t\tFetchParams = {},\n\t): Promise<TDocument[]> {\n\t\tconst { limit = Infinity, ...actualParams } = params\n\t\tconst resolvedParams = {\n\t\t\t...actualParams,\n\t\t\tpageSize: Math.min(\n\t\t\t\tlimit,\n\t\t\t\tactualParams.pageSize || this.defaultParams?.pageSize || MAX_PAGE_SIZE,\n\t\t\t),\n\t\t}\n\n\t\tconst documents: TDocument[] = []\n\t\tlet latestResult: Query<TDocument> | undefined\n\n\t\twhile (\n\t\t\t(!latestResult || latestResult.next_page) &&\n\t\t\tdocuments.length < limit\n\t\t) {\n\t\t\tconst page = latestResult ? latestResult.page + 1 : undefined\n\n\t\t\tlatestResult = await this.get<TDocument>({ ...resolvedParams, page })\n\t\t\tdocuments.push(...latestResult.results)\n\n\t\t\tif (latestResult.next_page) {\n\t\t\t\tawait new Promise((res) => setTimeout(res, GET_ALL_QUERY_DELAY))\n\t\t\t}\n\t\t}\n\n\t\treturn documents.slice(0, limit)\n\t}\n\n\t/**\n\t * Queries a document from the Prismic repository with a specific ID.\n\t *\n\t * @remarks\n\t * A document's UID is different from its ID. An ID is automatically generated\n\t * for all documents and is made available on its `id` property. A UID is\n\t * provided in the Prismic editor and is unique among all documents of its\n\t * custom type.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const document = await client.getByID(\"WW4bKScAAMAqmluX\")\n\t * ```\n\t *\n\t * @typeParam TDocument- Type of the Prismic document returned.\n\t *\n\t * @param id - ID of the document.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns The document with an ID matching the `id` parameter, if a matching\n\t * document exists.\n\t */\n\tasync getByID<TDocument extends TDocuments>(\n\t\tid: string,\n\t\tparams?: Partial<BuildQueryURLArgs> & FetchParams,\n\t): Promise<TDocument> {\n\t\treturn await this.getFirst<TDocument>(\n\t\t\tappendFilters(params, filter.at(\"document.id\", id)),\n\t\t)\n\t}\n\n\t/**\n\t * Queries documents from the Prismic repository with specific IDs.\n\t *\n\t * @remarks\n\t * A document's UID is different from its ID. An ID is automatically generated\n\t * for all documents and is made available on its `id` property. A UID is\n\t * provided in the Prismic editor and is unique among all documents of its\n\t * custom type.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.getByIDs([\n\t * \t\"WW4bKScAAMAqmluX\",\n\t * \t\"U1kTRgEAAC8A5ldS\",\n\t * ])\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param ids - A list of document IDs.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A paginated response containing documents with IDs matching the\n\t * `ids` parameter.\n\t */\n\tasync getByIDs<TDocument extends TDocuments>(\n\t\tids: string[],\n\t\tparams?: Partial<BuildQueryURLArgs> & FetchParams,\n\t): Promise<Query<TDocument>> {\n\t\treturn await this.get<TDocument>(\n\t\t\tappendFilters(params, filter.in(\"document.id\", ids)),\n\t\t)\n\t}\n\n\t/**\n\t * Queries all documents from the Prismic repository with specific IDs.\n\t *\n\t * This method may make multiple network requests to query all matching\n\t * content.\n\t *\n\t * @remarks\n\t * A document's UID is different from its ID. An ID is automatically generated\n\t * for all documents and is made available on its `id` property. A UID is\n\t * provided in the Prismic editor and is unique among all documents of its\n\t * custom type.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.getAllByIDs([\n\t * \t\"WW4bKScAAMAqmluX\",\n\t * \t\"U1kTRgEAAC8A5ldS\",\n\t * ])\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param ids - A list of document IDs.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A list of documents with IDs matching the `ids` parameter.\n\t */\n\tasync getAllByIDs<TDocument extends TDocuments>(\n\t\tids: string[],\n\t\tparams?: Partial<Omit<BuildQueryURLArgs, \"page\">> &\n\t\t\tGetAllParams &\n\t\t\tFetchParams,\n\t): Promise<TDocument[]> {\n\t\treturn await this.dangerouslyGetAll<TDocument>(\n\t\t\tappendFilters(params, filter.in(\"document.id\", ids)),\n\t\t)\n\t}\n\n\t/**\n\t * Queries a document from the Prismic repository with a specific UID and\n\t * custom type.\n\t *\n\t * @remarks\n\t * A document's UID is different from its ID. An ID is automatically generated\n\t * for all documents and is made available on its `id` property. A UID is\n\t * provided in the Prismic editor and is unique among all documents of its\n\t * custom type.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const document = await client.getByUID(\"blog_post\", \"my-first-post\")\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of the Prismic document returned.\n\t *\n\t * @param documentType - The API ID of the document's custom type.\n\t * @param uid - UID of the document.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns The document with a UID matching the `uid` parameter, if a\n\t * matching document exists.\n\t */\n\tasync getByUID<\n\t\tTDocument extends TDocuments,\n\t\tTDocumentType extends TDocument[\"type\"] = TDocument[\"type\"],\n\t>(\n\t\tdocumentType: TDocumentType,\n\t\tuid: string,\n\t\tparams?: Partial<BuildQueryURLArgs> & FetchParams,\n\t): Promise<ExtractDocumentType<TDocument, TDocumentType>> {\n\t\treturn await this.getFirst<ExtractDocumentType<TDocument, TDocumentType>>(\n\t\t\tappendFilters(params, [\n\t\t\t\ttypeFilter(documentType),\n\t\t\t\tfilter.at(`my.${documentType}.uid`, uid),\n\t\t\t]),\n\t\t)\n\t}\n\n\t/**\n\t * Queries document from the Prismic repository with specific UIDs and Custom\n\t * Type.\n\t *\n\t * @remarks\n\t * A document's UID is different from its ID. An ID is automatically generated\n\t * for all documents and is made available on its `id` property. A UID is\n\t * provided in the Prismic editor and is unique among all documents of its\n\t * custom type.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const document = await client.getByUIDs(\"blog_post\", [\n\t * \t\"my-first-post\",\n\t * \t\"my-second-post\",\n\t * ])\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of the Prismic document returned.\n\t *\n\t * @param documentType - The API ID of the document's custom type.\n\t * @param uids - A list of document UIDs.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A paginated response containing documents with UIDs matching the\n\t * `uids` parameter.\n\t */\n\tasync getByUIDs<\n\t\tTDocument extends TDocuments,\n\t\tTDocumentType extends TDocument[\"type\"] = TDocument[\"type\"],\n\t>(\n\t\tdocumentType: TDocumentType,\n\t\tuids: string[],\n\t\tparams?: Partial<BuildQueryURLArgs> & FetchParams,\n\t): Promise<Query<ExtractDocumentType<TDocument, TDocumentType>>> {\n\t\treturn await this.get<ExtractDocumentType<TDocument, TDocumentType>>(\n\t\t\tappendFilters(params, [\n\t\t\t\ttypeFilter(documentType),\n\t\t\t\tfilter.in(`my.${documentType}.uid`, uids),\n\t\t\t]),\n\t\t)\n\t}\n\n\t/**\n\t * Queries all documents from the Prismic repository with specific UIDs and\n\t * custom type.\n\t *\n\t * This method may make multiple network requests to query all matching\n\t * content.\n\t *\n\t * @remarks\n\t * A document's UID is different from its ID. An ID is automatically generated\n\t * for all documents and is made available on its `id` property. A UID is\n\t * provided in the Prismic editor and is unique among all documents of its\n\t * custom type.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.getAllByUIDs([\n\t * \t\"my-first-post\",\n\t * \t\"my-second-post\",\n\t * ])\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param documentType - The API ID of the document's custom type.\n\t * @param uids - A list of document UIDs.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A list of documents with UIDs matching the `uids` parameter.\n\t */\n\tasync getAllByUIDs<\n\t\tTDocument extends TDocuments,\n\t\tTDocumentType extends TDocument[\"type\"] = TDocument[\"type\"],\n\t>(\n\t\tdocumentType: TDocumentType,\n\t\tuids: string[],\n\t\tparams?: Partial<Omit<BuildQueryURLArgs, \"page\">> &\n\t\t\tGetAllParams &\n\t\t\tFetchParams,\n\t): Promise<ExtractDocumentType<TDocument, TDocumentType>[]> {\n\t\treturn await this.dangerouslyGetAll<\n\t\t\tExtractDocumentType<TDocument, TDocumentType>\n\t\t>(\n\t\t\tappendFilters(params, [\n\t\t\t\ttypeFilter(documentType),\n\t\t\t\tfilter.in(`my.${documentType}.uid`, uids),\n\t\t\t]),\n\t\t)\n\t}\n\n\t/**\n\t * Queries a singleton document from the Prismic repository for a specific\n\t * custom type.\n\t *\n\t * @remarks\n\t * A singleton document is one that is configured in Prismic to only allow one\n\t * instance. For example, a repository may be configured to contain just one\n\t * Settings document. This is in contrast to a repeatable custom type which\n\t * allows multiple instances of itself.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const document = await client.getSingle(\"settings\")\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of the Prismic document returned.\n\t *\n\t * @param documentType - The API ID of the singleton custom type.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns The singleton document for the custom type, if a matching document\n\t * exists.\n\t */\n\tasync getSingle<\n\t\tTDocument extends TDocuments,\n\t\tTDocumentType extends TDocument[\"type\"] = TDocument[\"type\"],\n\t>(\n\t\tdocumentType: TDocumentType,\n\t\tparams?: Partial<BuildQueryURLArgs> & FetchParams,\n\t): Promise<ExtractDocumentType<TDocument, TDocumentType>> {\n\t\treturn await this.getFirst<ExtractDocumentType<TDocument, TDocumentType>>(\n\t\t\tappendFilters(params, typeFilter(documentType)),\n\t\t)\n\t}\n\n\t/**\n\t * Queries documents from the Prismic repository for a specific custom type.\n\t *\n\t * Use `getAllByType` instead if you need to query all documents for a\n\t * specific custom type.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.getByType(\"blog_post\")\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param documentType - The API ID of the custom type.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A paginated response containing documents of the custom type.\n\t */\n\tasync getByType<\n\t\tTDocument extends TDocuments,\n\t\tTDocumentType extends TDocument[\"type\"] = TDocument[\"type\"],\n\t>(\n\t\tdocumentType: TDocumentType,\n\t\tparams?: Partial<BuildQueryURLArgs> & FetchParams,\n\t): Promise<Query<ExtractDocumentType<TDocument, TDocumentType>>> {\n\t\treturn await this.get<ExtractDocumentType<TDocument, TDocumentType>>(\n\t\t\tappendFilters(params, typeFilter(documentType)),\n\t\t)\n\t}\n\n\t/**\n\t * Queries all documents from the Prismic repository for a specific Custom\n\t * Type.\n\t *\n\t * This method may make multiple network requests to query all matching\n\t * content.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.getByType(\"blog_post\")\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param documentType - The API ID of the custom type.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A list of all documents of the custom type.\n\t */\n\tasync getAllByType<\n\t\tTDocument extends TDocuments,\n\t\tTDocumentType extends TDocument[\"type\"] = TDocument[\"type\"],\n\t>(\n\t\tdocumentType: TDocumentType,\n\t\tparams?: Partial<Omit<BuildQueryURLArgs, \"page\">> &\n\t\t\tGetAllParams &\n\t\t\tFetchParams,\n\t): Promise<ExtractDocumentType<TDocument, TDocumentType>[]> {\n\t\treturn await this.dangerouslyGetAll<\n\t\t\tExtractDocumentType<TDocument, TDocumentType>\n\t\t>(appendFilters(params, typeFilter(documentType)))\n\t}\n\n\t/**\n\t * Queries documents from the Prismic repository with a specific tag.\n\t *\n\t * Use `getAllByTag` instead if you need to query all documents with a\n\t * specific tag.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.getByTag(\"food\")\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param tag - The tag that must be included on a document.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A paginated response containing documents with the tag.\n\t */\n\tasync getByTag<TDocument extends TDocuments>(\n\t\ttag: string,\n\t\tparams?: Partial<BuildQueryURLArgs> & FetchParams,\n\t): Promise<Query<TDocument>> {\n\t\treturn await this.get<TDocument>(appendFilters(params, someTagsFilter(tag)))\n\t}\n\n\t/**\n\t * Queries all documents from the Prismic repository with a specific tag.\n\t *\n\t * This method may make multiple network requests to query all matching\n\t * content.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.getAllByTag(\"food\")\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param tag - The tag that must be included on a document.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A list of all documents with the tag.\n\t */\n\tasync getAllByTag<TDocument extends TDocuments>(\n\t\ttag: string,\n\t\tparams?: Partial<Omit<BuildQueryURLArgs, \"page\">> &\n\t\t\tGetAllParams &\n\t\t\tFetchParams,\n\t): Promise<TDocument[]> {\n\t\treturn await this.dangerouslyGetAll<TDocument>(\n\t\t\tappendFilters(params, someTagsFilter(tag)),\n\t\t)\n\t}\n\n\t/**\n\t * Queries documents from the Prismic repository with specific tags. A\n\t * document must be tagged with all of the queried tags to be included.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.getByEveryTag([\"food\", \"fruit\"])\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param tags - A list of tags that must be included on a document.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A paginated response containing documents with the tags.\n\t */\n\tasync getByEveryTag<TDocument extends TDocuments>(\n\t\ttags: string[],\n\t\tparams?: Partial<BuildQueryURLArgs> & FetchParams,\n\t): Promise<Query<TDocument>> {\n\t\treturn await this.get<TDocument>(\n\t\t\tappendFilters(params, everyTagFilter(tags)),\n\t\t)\n\t}\n\n\t/**\n\t * Queries documents from the Prismic repository with specific tags. A\n\t * document must be tagged with all of the queried tags to be included.\n\t *\n\t * This method may make multiple network requests to query all matching\n\t * content.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.getAllByEveryTag([\"food\", \"fruit\"])\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param tags - A list of tags that must be included on a document.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A list of all documents with the tags.\n\t */\n\tasync getAllByEveryTag<TDocument extends TDocuments>(\n\t\ttags: string[],\n\t\tparams?: Partial<Omit<BuildQueryURLArgs, \"page\">> &\n\t\t\tGetAllParams &\n\t\t\tFetchParams,\n\t): Promise<TDocument[]> {\n\t\treturn await this.dangerouslyGetAll<TDocument>(\n\t\t\tappendFilters(params, everyTagFilter(tags)),\n\t\t)\n\t}\n\n\t/**\n\t * Queries documents from the Prismic repository with specific tags. A\n\t * document must be tagged with at least one of the queried tags to be\n\t * included.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.getByEveryTag([\"food\", \"fruit\"])\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param tags - A list of tags that must be included on a document.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A paginated response containing documents with at least one of the\n\t * tags.\n\t */\n\tasync getBySomeTags<TDocument extends TDocuments>(\n\t\ttags: string[],\n\t\tparams?: Partial<BuildQueryURLArgs> & FetchParams,\n\t): Promise<Query<TDocument>> {\n\t\treturn await this.get<TDocument>(\n\t\t\tappendFilters(params, someTagsFilter(tags)),\n\t\t)\n\t}\n\n\t/**\n\t * Queries documents from the Prismic repository with specific tags. A\n\t * document must be tagged with at least one of the queried tags to be\n\t * included.\n\t *\n\t * This method may make multiple network requests to query all matching\n\t * content.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const response = await client.getAllBySomeTags([\"food\", \"fruit\"])\n\t * ```\n\t *\n\t * @typeParam TDocument - Type of Prismic documents returned.\n\t *\n\t * @param tags - A list of tags that must be included on a document.\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A list of all documents with at least one of the tags.\n\t */\n\tasync getAllBySomeTags<TDocument extends TDocuments>(\n\t\ttags: string[],\n\t\tparams?: Partial<Omit<BuildQueryURLArgs, \"page\">> &\n\t\t\tGetAllParams &\n\t\t\tFetchParams,\n\t): Promise<TDocument[]> {\n\t\treturn await this.dangerouslyGetAll<TDocument>(\n\t\t\tappendFilters(params, someTagsFilter(tags)),\n\t\t)\n\t}\n\n\t/**\n\t * Returns metadata about the Prismic repository, such as its refs, releases,\n\t * and custom types.\n\t *\n\t * @returns Repository metadata.\n\t */\n\tasync getRepository(params?: FetchParams): Promise<Repository> {\n\t\t// TODO: Restore when Authorization header support works in browsers with CORS.\n\t\t// return await this.fetch<Repository>(this.endpoint);\n\n\t\tconst url = new URL(this.documentAPIEndpoint)\n\n\t\tif (this.accessToken) {\n\t\t\turl.searchParams.set(\"access_token\", this.accessToken)\n\t\t}\n\n\t\treturn await this.fetch<Repository>(url.toString(), params)\n\t}\n\n\t/**\n\t * Returns a list of all refs for the Prismic repository.\n\t *\n\t * Refs are used to identify which version of the repository's content should\n\t * be queried. All repositories will have at least one ref pointing to the\n\t * latest published content called the \"master ref\".\n\t *\n\t * @returns A list of all refs for the Prismic repository.\n\t */\n\tasync getRefs(params?: FetchParams): Promise<Ref[]> {\n\t\tconst repository = await this.getRepository(params)\n\n\t\treturn repository.refs\n\t}\n\n\t/**\n\t * Returns a ref for the Prismic repository with a matching ID.\n\t *\n\t * @param id - ID of the ref.\n\t *\n\t * @returns The ref with a matching ID, if it exists.\n\t */\n\tasync getRefByID(id: string, params?: FetchParams): Promise<Ref> {\n\t\tconst refs = await this.getRefs(params)\n\n\t\treturn findRefByID(refs, id)\n\t}\n\n\t/**\n\t * Returns a ref for the Prismic repository with a matching label.\n\t *\n\t * @param label - Label of the ref.\n\t *\n\t * @returns The ref with a matching label, if it exists.\n\t */\n\tasync getRefByLabel(label: string, params?: FetchParams): Promise<Ref> {\n\t\tconst refs = await this.getRefs(params)\n\n\t\treturn findRefByLabel(refs, label)\n\t}\n\n\t/**\n\t * Returns the master ref for the Prismic repository. The master ref points to\n\t * the repository's latest published content.\n\t *\n\t * @returns The repository's master ref.\n\t */\n\tasync getMasterRef(params?: FetchParams): Promise<Ref> {\n\t\tconst refs = await this.getRefs(params)\n\n\t\treturn findMasterRef(refs)\n\t}\n\n\t/**\n\t * Returns a list of all Releases for the Prismic repository. Releases are\n\t * used to group content changes before publishing.\n\t *\n\t * @returns A list of all Releases for the Prismic repository.\n\t */\n\tasync getReleases(params?: FetchParams): Promise<Ref[]> {\n\t\tconst refs = await this.getRefs(params)\n\n\t\treturn refs.filter((ref) => !ref.isMasterRef)\n\t}\n\n\t/**\n\t * Returns a Release for the Prismic repository with a matching ID.\n\t *\n\t * @param id - ID of the Release.\n\t *\n\t * @returns The Release with a matching ID, if it exists.\n\t */\n\tasync getReleaseByID(id: string, params?: FetchParams): Promise<Ref> {\n\t\tconst releases = await this.getReleases(params)\n\n\t\treturn findRefByID(releases, id)\n\t}\n\n\t/**\n\t * Returns a Release for the Prismic repository with a matching label.\n\t *\n\t * @param label - Label of the ref.\n\t *\n\t * @returns The ref with a matching label, if it exists.\n\t */\n\tasync getReleaseByLabel(label: string, params?: FetchParams): Promise<Ref> {\n\t\tconst releases = await this.getReleases(params)\n\n\t\treturn findRefByLabel(releases, label)\n\t}\n\n\t/**\n\t * Returns a list of all tags used in the Prismic repository.\n\t *\n\t * @returns A list of all tags used in the repository.\n\t */\n\tasync getTags(params?: FetchParams): Promise<string[]> {\n\t\ttry {\n\t\t\tconst tagsForm = await this.getCachedRepositoryForm(\"tags\", params)\n\n\t\t\tconst url = new URL(tagsForm.action)\n\n\t\t\tif (this.accessToken) {\n\t\t\t\turl.searchParams.set(\"access_token\", this.accessToken)\n\t\t\t}\n\n\t\t\treturn await this.fetch<string[]>(url.toString(), params)\n\t\t} catch {\n\t\t\tconst repository = await this.getRepository(params)\n\n\t\t\treturn repository.tags\n\t\t}\n\t}\n\n\t/**\n\t * Builds a URL used to query content from the Prismic repository.\n\t *\n\t * @param params - Parameters to filter, sort, and paginate the results.\n\t *\n\t * @returns A URL string that can be requested to query content.\n\t */\n\tasync buildQueryURL({\n\t\tsignal,\n\t\tfetchOptions,\n\t\t...params\n\t}: Partial<BuildQueryURLArgs> & FetchParams = {}): Promise<string> {\n\t\tconst ref =\n\t\t\tparams.ref || (await this.getResolvedRefString({ signal, fetchOptions }))\n\t\tconst integrationFieldsRef =\n\t\t\tparams.integrationFieldsRef ||\n\t\t\t(await this.getCachedRepository({ signal, fetchOptions }))\n\t\t\t\t.integrationFieldsRef ||\n\t\t\tundefined\n\n\t\treturn buildQueryURL(this.documentAPIEndpoint, {\n\t\t\t...this.defaultParams,\n\t\t\t...params,\n\t\t\tref,\n\t\t\tintegrationFieldsRef,\n\t\t\troutes: params.routes || this.routes,\n\t\t\tbrokenRoute: params.brokenRoute || this.brokenRoute,\n\t\t\taccessToken: params.accessToken || this.accessToken,\n\t\t})\n\t}\n\n\t/**\n\t * Determines the URL for a previewed document during an active preview\n\t * session. The result of this method should be used to redirect the user to\n\t * the document's URL.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * \tconst url = client.resolvePreviewURL({\n\t * \tlinkResolver: (document) => `/${document.uid}`\n\t * \tdefaultURL: '/'\n\t * \t})\n\t * ```\n\t *\n\t * @param args - Arguments to configure the URL resolving.\n\t *\n\t * @returns The URL for the previewed document during an active preview\n\t * session. The user should be redirected to this URL.\n\t */\n\tasync resolvePreviewURL<LinkResolverReturnType>(\n\t\targs: ResolvePreviewArgs<LinkResolverReturnType> & FetchParams,\n\t): Promise<string> {\n\t\tlet documentID: string | undefined | null = args.documentID\n\t\tlet previewToken: string | undefined | null = args.previewToken\n\n\t\tif (typeof globalThis.location !== \"undefined\") {\n\t\t\tconst searchParams = new URLSearchParams(globalThis.location.search)\n\n\t\t\tdocumentID = documentID || searchParams.get(\"documentId\")\n\t\t\tpreviewToken = previewToken || searchParams.get(\"token\")\n\t\t} else if (this.refState.httpRequest) {\n\t\t\tif (\"query\" in this.refState.httpRequest) {\n\t\t\t\tdocumentID =\n\t\t\t\t\tdocumentID || (this.refState.httpRequest.query?.documentId as string)\n\t\t\t\tpreviewToken =\n\t\t\t\t\tpreviewToken || (this.refState.httpRequest.query?.token as string)\n\t\t\t} else if (\n\t\t\t\t\"url\" in this.refState.httpRequest &&\n\t\t\t\tthis.refState.httpRequest.url\n\t\t\t) {\n\t\t\t\t// Including \"missing-host://\" by default\n\t\t\t\t// handles a case where Next.js Route Handlers\n\t\t\t\t// only provide the pathname and search\n\t\t\t\t// parameters in the `url` property\n\t\t\t\t// (e.g. `/api/preview?foo=bar`).\n\t\t\t\tconst searchParams = new URL(\n\t\t\t\t\tthis.refState.httpRequest.url,\n\t\t\t\t\t\"missing-host://\",\n\t\t\t\t).searchParams\n\n\t\t\t\tdocumentID = documentID || searchParams.get(\"documentId\")\n\t\t\t\tpreviewToken = previewToken || searchParams.get(\"token\")\n\t\t\t}\n\t\t}\n\n\t\tif (documentID != null && previewToken != null) {\n\t\t\tconst document = await this.getByID(documentID, {\n\t\t\t\tref: previewToken,\n\t\t\t\tlang: \"*\",\n\t\t\t\tsignal: args.signal,\n\t\t\t\tfetchOptions: args.fetchOptions,\n\t\t\t})\n\n\t\t\tconst url = asLink(document, { linkResolver: args.linkResolver })\n\n\t\t\tif (typeof url === \"string\") {\n\t\t\t\treturn url\n\t\t\t}\n\t\t}\n\n\t\treturn args.defaultURL\n\t}\n\n\t/**\n\t * Configures the client to query the latest published content for all future\n\t * queries.\n\t *\n\t * If the `ref` parameter is provided during a query, it takes priority for\n\t * that query.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * await client.queryLatestContent()\n\t * const document = await client.getByID(\"WW4bKScAAMAqmluX\")\n\t * ```\n\t */\n\tqueryLatestContent(): void {\n\t\tthis.refState.mode = RefStateMode.Master\n\t}\n\n\t/**\n\t * Configures the client to query content from a specific Release identified\n\t * by its ID for all future queries.\n\t *\n\t * If the `ref` parameter is provided during a query, it takes priority for\n\t * that query.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * await client.queryContentFromReleaseByID(\"YLB7OBAAACMA7Cpa\")\n\t * const document = await client.getByID(\"WW4bKScAAMAqmluX\")\n\t * ```\n\t *\n\t * @param releaseID - The ID of the Release.\n\t */\n\tqueryContentFromReleaseByID(releaseID: string): void {\n\t\tthis.refState = {\n\t\t\t...this.refState,\n\t\t\tmode: RefStateMode.ReleaseID,\n\t\t\treleaseID,\n\t\t}\n\t}\n\n\t/**\n\t * Configures the client to query content from a specific Release identified\n\t * by its label for all future queries.\n\t *\n\t * If the `ref` parameter is provided during a query, it takes priority for\n\t * that query.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * await client.queryContentFromReleaseByLabel(\"My Release\")\n\t * const document = await client.getByID(\"WW4bKScAAMAqmluX\")\n\t * ```\n\t *\n\t * @param releaseLabel - The label of the Release.\n\t */\n\tqueryContentFromReleaseByLabel(releaseLabel: string): void {\n\t\tthis.refState = {\n\t\t\t...this.refState,\n\t\t\tmode: RefStateMode.ReleaseLabel,\n\t\t\treleaseLabel,\n\t\t}\n\t}\n\n\t/**\n\t * Configures the client to query content from a specific ref. The ref can be\n\t * provided as a string or a function.\n\t *\n\t * If a function is provided, the ref is fetched lazily before each query. The\n\t * function may also be asynchronous.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * await client.queryContentFromRef(\"my-ref\")\n\t * const document = await client.getByID(\"WW4bKScAAMAqmluX\")\n\t * ```\n\t *\n\t * @param ref - The ref or a function that returns the ref from which to query\n\t * content.\n\t */\n\tqueryContentFromRef(ref: RefStringOrThunk): void {\n\t\tthis.refState = {\n\t\t\t...this.refState,\n\t\t\tmode: RefStateMode.Manual,\n\t\t\tref,\n\t\t}\n\t}\n\n\t/**\n\t * A `fetch()` function to be used with GraphQL clients configured for\n\t * Prismic's GraphQL API. It automatically applies the necessary `prismic-ref`\n\t * and Authorization headers. Queries will automatically be minified by\n\t * removing whitespace where possible.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const graphQLClient = new ApolloClient({\n\t * \tlink: new HttpLink({\n\t * \t\turi: prismic.getGraphQLEndpoint(repositoryName),\n\t * \t\t// Provide `client.graphQLFetch` as the fetch implementation.\n\t * \t\tfetch: client.graphQLFetch,\n\t * \t\t// Using GET is required.\n\t * \t\tuseGETForQueries: true,\n\t * \t}),\n\t * \tcache: new InMemoryCache(),\n\t * })\n\t * ```\n\t *\n\t * @param input - The `fetch()` `input` parameter. Only strings are supported.\n\t * @param init - The `fetch()` `init` parameter. Only plain objects are\n\t * supported.\n\t *\n\t * @returns The `fetch()` Response for the request.\n\t *\n\t * @experimental\n\t */\n\tasync graphQLFetch(\n\t\tinput: RequestInfo,\n\t\tinit?: Omit<RequestInit, \"signal\"> & { signal?: AbortSignalLike },\n\t): Promise<Response> {\n\t\tconst cachedRepository = await this.getCachedRepository()\n\t\tconst ref = await this.getResolvedRefString()\n\n\t\tconst unsanitizedHeaders: Record<string, string> = {\n\t\t\t\"Prismic-ref\": ref,\n\t\t\tAuthorization: this.accessToken ? `Token ${this.accessToken}` : \"\",\n\t\t\t// Asserting `init.headers` is a Record since popular GraphQL\n\t\t\t// libraries pass this as a Record. Header objects as input\n\t\t\t// are unsupported.\n\t\t\t...(init ? (init.headers as Record<string, string>) : {}),\n\t\t}\n\n\t\tif (cachedRepository.integrationFieldsRef) {\n\t\t\tunsanitizedHeaders[\"Prismic-integration-field-ref\"] =\n\t\t\t\tcachedRepository.integrationFieldsRef\n\t\t}\n\n\t\t// Normalize header keys to lowercase. This prevents header\n\t\t// conflicts between the Prismic client and the GraphQL\n\t\t// client.\n\t\tconst headers: Record<string, string> = {}\n\t\tfor (const key in unsanitizedHeaders) {\n\t\t\tif (unsanitizedHeaders[key]) {\n\t\t\t\theaders[key.toLowerCase()] =\n\t\t\t\t\tunsanitizedHeaders[key as keyof typeof unsanitizedHeaders]\n\t\t\t}\n\t\t}\n\n\t\tconst url = new URL(\n\t\t\t// Asserting `input` is a string since popular GraphQL\n\t\t\t// libraries pass this as a string. Request objects as\n\t\t\t// input are unsupported.\n\t\t\tinput as string,\n\t\t)\n\n\t\t// This prevents the request from being cached unnecessarily.\n\t\t// Without adding this `ref` param, re-running a query\n\t\t// could return a locally cached response, even if the\n\t\t// `ref` changed. This happens because the URL is\n\t\t// identical when the `ref` is not included. Caches may ignore\n\t\t// headers.\n\t\t//\n\t\t// The Prismic GraphQL