UNPKG

gatsby-source-prismic

Version:

Gatsby source plugin for building websites using Prismic as a data source

1 lines 73.6 kB
{"version":3,"file":"index.cjs","sources":["../src/types.ts","../src/constants.ts","../src/runtime/createGetProxy.ts","../src/runtime/normalizers/alternateLanguages.ts","../src/runtime/normalizers/document.ts","../src/runtime/normalizers/documentData.ts","../src/runtime/normalizers/group.ts","../src/lib/sanitizeImageURL.ts","../src/lib/stripURLParameters.ts","../src/runtime/normalizers/image.ts","../src/runtime/normalizers/link.ts","../src/runtime/normalizers/structuredText.ts","../src/runtime/normalizers/slice.ts","../src/runtime/normalizers/slices.ts","../src/runtime/normalize.ts","../src/runtime/typePaths.ts","../src/runtime/serializePath.ts","../src/runtime/serializeTypePaths.ts","../src/runtime/runtime.ts"],"sourcesContent":["import * as gatsby from \"gatsby\";\nimport * as gatsbyFs from \"gatsby-source-filesystem\";\nimport * as imgixGatsby from \"@imgix/gatsby\";\nimport * as prismic from \"@prismicio/client\";\nimport * as prismicH from \"@prismicio/helpers\";\nimport * as prismicT from \"@prismicio/types\";\nimport * as prismicCustomTypes from \"@prismicio/custom-types-client\";\nimport * as gqlc from \"graphql-compose\";\nimport * as RTE from \"fp-ts/ReaderTaskEither\";\nimport { NodeHelpers } from \"gatsby-node-helpers\";\n\nimport { Runtime } from \"./runtime\";\n\nexport type Mutable<T> = {\n\t-readonly [P in keyof T]: T[P];\n};\n\nexport type UnknownRecord<K extends PropertyKey = PropertyKey> = Record<\n\tK,\n\tunknown\n>;\n\nexport type IterableElement<TargetIterable> = TargetIterable extends Iterable<\n\tinfer ElementType\n>\n\t? ElementType\n\t: never;\n\nexport type JoiValidationError = InstanceType<\n\tgatsby.PluginOptionsSchemaArgs[\"Joi\"][\"ValidationError\"]\n>;\n\nexport type PrismicDocumentNodeInput<\n\tTDocument extends prismicT.PrismicDocument = prismicT.PrismicDocument,\n> = TDocument & gatsby.NodeInput & { prismicId: string };\n\nexport enum TypePathKind {\n\tCustomType = \"CustomType\",\n\tSharedSliceVariation = \"SharedSliceVariation\",\n\tField = \"Field\",\n}\n\nexport interface TypePath {\n\tkind: TypePathKind;\n\tpath: string[];\n\ttype: PrismicTypePathType;\n}\n\nexport interface SerializedTypePath extends Omit<TypePath, \"path\"> {\n\tpath: string;\n}\n\nexport type TypePathNode = TypePath & gatsby.Node;\n\nexport type TransformFieldNameFn = (fieldName: string) => string;\n\nexport interface Dependencies {\n\tprismicClient: prismic.Client;\n\tcreateTypes: gatsby.Actions[\"createTypes\"];\n\tcreateNode: gatsby.Actions[\"createNode\"];\n\tbuildObjectType: gatsby.NodePluginSchema[\"buildObjectType\"];\n\tbuildUnionType: gatsby.NodePluginSchema[\"buildUnionType\"];\n\tbuildEnumType: gatsby.NodePluginSchema[\"buildEnumType\"];\n\tbuildScalarType: gatsby.NodePluginSchema[\"buildScalarType\"];\n\tbuildInterfaceType: gatsby.NodePluginSchema[\"buildInterfaceType\"];\n\tgetNode: gatsby.SourceNodesArgs[\"getNode\"];\n\tgetNodes: gatsby.SourceNodesArgs[\"getNodes\"];\n\ttouchNode: gatsby.Actions[\"touchNode\"];\n\tdeleteNode: gatsby.Actions[\"deleteNode\"];\n\tcreateNodeId: gatsby.NodePluginArgs[\"createNodeId\"];\n\tcreateContentDigest: gatsby.NodePluginArgs[\"createContentDigest\"];\n\tschema: gatsby.NodePluginSchema;\n\tcache: gatsby.GatsbyCache;\n\tstore: gatsby.Store;\n\treporter: gatsby.Reporter;\n\treportInfo: gatsby.Reporter[\"info\"];\n\treportWarning: gatsby.Reporter[\"warn\"];\n\treportVerbose: gatsby.Reporter[\"verbose\"];\n\tglobalNodeHelpers: NodeHelpers;\n\tnodeHelpers: NodeHelpers;\n\tpluginOptions: PluginOptions;\n\twebhookBody?: unknown;\n\tcreateRemoteFileNode: typeof gatsbyFs.createRemoteFileNode;\n\ttransformFieldName: TransformFieldNameFn;\n\truntime: Runtime;\n}\n\ntype ShouldDownloadFilesPredicate = (\n\tfield: prismicT.ImageFieldImage | prismicT.LinkToMediaField,\n) => boolean;\n\nexport type UnpreparedPluginOptions = gatsby.PluginOptions & {\n\trepositoryName: string;\n\taccessToken?: string;\n\tapiEndpoint?: string;\n\tcustomTypesApiEndpoint?: string;\n\treleaseID?: string;\n\tgraphQuery?: string;\n\tfetchLinks?: string[];\n\tlang?: string;\n\tpageSize?: number;\n\tlinkResolver?: prismicH.LinkResolverFunction;\n\troutes?: prismic.Route[];\n\thtmlSerializer?: prismicH.HTMLFunctionSerializer | prismicH.HTMLMapSerializer;\n\timageImgixParams?: imgixGatsby.ImgixUrlParams;\n\timagePlaceholderImgixParams?: imgixGatsby.ImgixUrlParams;\n\ttypePrefix?: string;\n\twebhookSecret?: string;\n\tshouldDownloadFiles?:\n\t\t| boolean\n\t\t| ShouldDownloadFilesPredicate\n\t\t| Record<string, boolean | ShouldDownloadFilesPredicate>;\n\tcreateRemoteFileNode?: typeof gatsbyFs.createRemoteFileNode;\n\ttransformFieldName?: TransformFieldNameFn;\n\tfetch?: prismic.FetchLike & prismicCustomTypes.FetchLike;\n\n\tcustomTypesApiToken?: string;\n\t/**\n\t * A record of all Custom Type API IDs mapped to their models.\n\t *\n\t * @deprecated Use the `customTypeModels` plugin option.\n\t */\n\tschemas?: Record<string, prismicT.CustomTypeModelDefinition>;\n\t/**\n\t * A list of all Custom Types models using the Custom Types API object shape.\n\t */\n\tcustomTypeModels?: prismicT.CustomTypeModel[];\n\t/**\n\t * A list of all Shared Slice models.\n\t */\n\tsharedSliceModels?: prismicT.SharedSliceModel[];\n};\n\nexport type PluginOptions = UnpreparedPluginOptions &\n\tRequired<\n\t\tPick<\n\t\t\tUnpreparedPluginOptions,\n\t\t\t| \"apiEndpoint\"\n\t\t\t| \"customTypeModels\"\n\t\t\t| \"sharedSliceModels\"\n\t\t\t| \"imageImgixParams\"\n\t\t\t| \"imagePlaceholderImgixParams\"\n\t\t\t| \"shouldDownloadFiles\"\n\t\t\t| \"createRemoteFileNode\"\n\t\t\t| \"transformFieldName\"\n\t\t\t| \"fetch\"\n\t\t>\n\t>;\n\nexport type FieldConfigCreator<\n\tTSchema extends prismicT.CustomTypeModelField = prismicT.CustomTypeModelField,\n> = (\n\tpath: string[],\n\tschema: TSchema,\n) => RTE.ReaderTaskEither<\n\tDependencies,\n\tError,\n\tgqlc.ObjectTypeComposerFieldConfigDefinition<unknown, unknown>\n>;\n\nexport type PrismicTypePathType =\n\t| PrismicSpecialType\n\t| typeof prismicT.CustomTypeModelFieldType[keyof typeof prismicT.CustomTypeModelFieldType]\n\t| typeof prismicT.CustomTypeModelSliceType[keyof typeof prismicT.CustomTypeModelSliceType];\n\nexport enum PrismicSpecialType {\n\tDocument = \"Document\",\n\tDocumentData = \"DocumentData\",\n\tSharedSliceVariation = \"SharedSliceVariation\",\n\tUnknown = \"Unknown\",\n}\n\nexport interface PrismicAPIDocumentNode\n\textends prismicT.PrismicDocument,\n\t\tgatsby.Node {\n\tprismicId: string;\n}\n\nexport type PrismicWebhookBody =\n\t| PrismicWebhookBodyApiUpdate\n\t| PrismicWebhookBodyTestTrigger;\n\nexport enum PrismicWebhookType {\n\tAPIUpdate = \"api-update\",\n\tTestTrigger = \"test-trigger\",\n}\n\ninterface PrismicWebhookBodyBase {\n\ttype: PrismicWebhookType;\n\tdomain: string;\n\tapiUrl: string;\n\tsecret: string | null;\n}\n\nexport interface PrismicWebhookBodyApiUpdate extends PrismicWebhookBodyBase {\n\ttype: PrismicWebhookType.APIUpdate;\n\tmasterRef?: string;\n\treleases: PrismicWebhookOperations<PrismicWebhookRelease>;\n\tmasks: PrismicWebhookOperations<PrismicWebhookMask>;\n\ttags: PrismicWebhookOperations<PrismicWebhookTag>;\n\tdocuments: string[];\n\texperiments?: PrismicWebhookOperations<PrismicWebhookExperiment>;\n}\n\nexport interface PrismicWebhookBodyTestTrigger extends PrismicWebhookBodyBase {\n\ttype: PrismicWebhookType.TestTrigger;\n}\n\ninterface PrismicWebhookOperations<T> {\n\tupdate?: T[];\n\taddition?: T[];\n\tdeletion?: T[];\n}\n\ninterface PrismicWebhookMask {\n\tid: string;\n\tlabel: string;\n}\n\ninterface PrismicWebhookTag {\n\tid: string;\n}\n\nexport interface PrismicWebhookRelease {\n\tid: string;\n\tref: string;\n\tlabel: string;\n\tdocuments: string[];\n}\n\n/**\n * @deprecated Experiments are no longer supported by Prismic.\n */\ninterface PrismicWebhookExperiment {\n\tid: string;\n\tname: string;\n\tvariations: PrismicWebhookExperimentVariation[];\n}\n\n/**\n * @deprecated Experiments are no longer supported by Prismic.\n */\ninterface PrismicWebhookExperimentVariation {\n\tid: string;\n\tref: string;\n\tlabel: string;\n}\n\nexport type PrismicCustomTypeApiResponse = PrismicCustomTypeApiCustomType[];\n\nexport interface PrismicCustomTypeApiCustomType<\n\tModel extends prismicT.CustomTypeModel = prismicT.CustomTypeModel,\n> {\n\tid: string;\n\tlabel: string;\n\trepeatable: boolean;\n\tjson: Model;\n}\n","/**\n * Name of the plugin used to identify Nodes owned by this plugin.\n *\n * Note: This should always be in sync with package.json's `name` field.\n */\nexport const PLUGIN_NAME = \"gatsby-source-prismic\";\n\n/**\n * Global prefix used for all GraphQL types and, where necessary, fields.\n */\nexport const GLOBAL_TYPE_PREFIX = \"Prismic\";\n\n/**\n * Default endpoint used to fetch custom type JSON schemas from Prismic's Custom Type API.\n *\n * @see https://prismic.io/docs/technologies/custom-types-api\n */\nexport const DEFAULT_CUSTOM_TYPES_API_ENDPOINT =\n\t\"https://customtypes.prismic.io/customtypes\";\n\n/**\n * Prismic API document fields returned for image fields that are **not** thumbnails.\n *\n * These fields are filtered out from the API response to extract the field's\n * thumbnails. The API includes thumbnails adjacent to these fields.\n */\nexport const PRISMIC_API_IMAGE_FIELDS = [\n\t\"alt\",\n\t\"copyright\",\n\t\"dimensions\",\n\t\"url\",\n];\n\n/**\n * Default Imgix URL parameters for `gatsby-plugin-image` fields.\n *\n * These defaults provide a good balance between image quality and filesize.\n *\n * @see https://docs.imgix.com/apis/rendering\n */\nexport const DEFAULT_IMGIX_PARAMS = {\n\tauto: \"compress,format\",\n\n\t// The following values are not included by Prismic's URLs by default.\n\tfit: \"max\",\n} as const;\n\n/**\n * Default Imgix URL parameters for `gatsby-plugin-image` placeholder images.\n *\n * These defaults provide a good balance between image quality and filesize.\n * They are merged with the `imageImgixParams` plugin option.\n *\n * @see https://docs.imgix.com/apis/rendering\n */\nexport const DEFAULT_PLACEHOLDER_IMGIX_PARAMS = {\n\tw: 100,\n\n\t// Makes the image appear less pixelated when stretched to large sizes.\n\t//\n\t// TODO: This value can be removed if `gatsby-plugin-image` implements\n\t// CSS-based blurring.\n\tblur: 15,\n} as const;\n\n/**\n * Default Prismic language option used when fetching documents. The current\n * default fetches all languages.\n *\n * @see https://prismic.io/docs/technologies/query-by-language-rest-api\n */\nexport const DEFAULT_LANG = \"*\";\n\n/**\n * Format used for all plugin reporting. Includes the plugin's name and the\n * instance's repository name (helpful when multiple repositories are configured).\n */\nexport const REPORTER_TEMPLATE = `gatsby-source-prismic(%s) - %s`;\n\n/**\n * Root node field used to compare static data with preview data. If values are\n * equal, the preview node can be treated as an updated version of the static node.\n *\n * This is an internal-use-only field used by `gatsby-plugin-prismic-previews`.\n */\nexport const PREVIEWABLE_NODE_ID_FIELD = \"_previewable\";\n\n/**\n * Message displayed to the user when a webhook's secret does not match the\n * secret configured in the site's `gatsby-config.js`.\n */\nexport const WEBHOOK_SECRET_MISMATCH_MSG =\n\t\"A webhook was received, but the webhook secret did not match the webhook secret provided in the plugin options. If this is unexpected, verify that the `webhookSecret` plugin option matches the webhook secret in your Prismic repository.\";\n\n/**\n * Message displayed to the user when a `test-trigger` webhook is received.\n */\nexport const WEBHOOK_TEST_TRIGGER_SUCCESS_MSG =\n\t\"Success! Received a test trigger webhook. When changes to your content are saved, Gatsby will automatically fetch the changes.\";\n\n/**\n * Message displayed to the user when a missing custom type schema is detected.\n */\nexport const MISSING_SCHEMAS_MSG =\n\t\"JSON schemas for all custom types are required\";\n\n/**\n * Format used to inform the user of a missing schema.\n */\nexport const MISSING_SCHEMA_MSG =\n\t'JSON model for \"%s\" is missing. If the Custom Type is no longer in use, you may provide \"{}\" as the JSON model.';\n\nexport const FORBIDDEN_ACCESS_WITHOUT_ACCESS_TOKEN =\n\t\"Unable to access the Prismic repository. Check the repository name. If the repository is secured, provide an access token.\";\n\nexport const FORBIDDEN_ACCESS_WITH_ACCESS_TOKEN =\n\t\"Unable to access the Prismic repository. Check that the correct repository name and access token are provided.\";\n\nexport const FORBIDDEN_CUSTOM_TYPES_API_ACCESS =\n\t\"Unable to access the Prismic Custom Types API. Check the customTypesApiToken option.\";\n\nexport const NON_EXISTENT_RELEASE_WITH_ACCESS_TOKEN_MSG =\n\t'The given Release ID (\"%s\") could not be found. If the Release ID is correct, check that your access token has permission to view Releases.';\n\nexport const NON_EXISTENT_RELEASE_WITHOUT_ACCESS_TOKEN_MSG =\n\t'The given Release ID (\"%s\") could not be found. If the Release ID is correct, you may need to provide an access token with permission to view Releases.';\n","/**\n * Symbol used to identify if a value is a proxy. Attach this to proxies (done\n * automatically via `lib/createGetProxy`).\n */\nexport const IS_PROXY = Symbol(\"IS_PROXY\");\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const createGetProxy = <T extends object>(\n\ttarget: T,\n\tget: ProxyHandler<T>[\"get\"],\n): T => {\n\t// @ts-expect-error - We are forcibly adding this \"is proxy\" property\n\ttarget[IS_PROXY] = true;\n\n\treturn new Proxy(target, { get });\n};\n","import * as prismicT from \"@prismicio/types\";\n\nimport { createGetProxy } from \"../createGetProxy\";\nimport { NormalizeConfig, NormalizerDependencies } from \"../types\";\n\nimport { NormalizedDocumentValue } from \"./document\";\n\nexport type NormalizeAlternateLanguagesConfig = NormalizeConfig<\n\tprismicT.PrismicDocument[\"alternate_languages\"]\n> &\n\tPick<NormalizerDependencies, \"getNode\">;\n\nexport type NormalizedAlternateLanguagesValue = (prismicT.AlternateLanguage & {\n\tdocument?: NormalizedDocumentValue | null;\n\traw: prismicT.AlternateLanguage;\n})[];\n\nexport const alternateLanguages = (\n\tconfig: NormalizeAlternateLanguagesConfig,\n): NormalizedAlternateLanguagesValue => {\n\treturn config.value.map((alternateLanguage) => {\n\t\tconst value = {\n\t\t\t...alternateLanguage,\n\t\t\traw: alternateLanguage,\n\t\t};\n\n\t\treturn createGetProxy(value, (target, prop, receiver) => {\n\t\t\tif (prop === \"document\") {\n\t\t\t\treturn config.getNode(value.id) || null;\n\t\t\t}\n\n\t\t\treturn Reflect.get(target, prop, receiver);\n\t\t});\n\t});\n};\n","import * as prismicT from \"@prismicio/types\";\nimport * as prismicH from \"@prismicio/helpers\";\nimport * as gatsby from \"gatsby\";\n\nimport {\n\tNormalizeConfig,\n\tNormalizedValueMap,\n\tNormalizerDependencies,\n} from \"../types\";\nimport { normalize } from \"../normalize\";\nimport {\n\talternateLanguages,\n\tNormalizedAlternateLanguagesValue,\n} from \"./alternateLanguages\";\nimport { NormalizedDocumentDataValue } from \"./documentData\";\n\nexport const isDocument = (\n\tvalue: unknown,\n): value is prismicT.PrismicDocument => {\n\treturn typeof value === \"object\" && value !== null && \"type\" in value;\n};\n\ntype NormalizeDocumentConfig<Value extends prismicT.PrismicDocument> =\n\tNormalizeConfig<Value> & NormalizerDependencies;\n\nexport type NormalizedDocumentValue<\n\tValue extends prismicT.PrismicDocument = prismicT.PrismicDocument,\n> = Omit<Value, \"alternate_languages\" | \"data\"> & {\n\t__typename: string;\n\t_previewable: string;\n\tprismicId: string;\n\talternate_languages: NormalizedAlternateLanguagesValue;\n\tdata: NormalizedValueMap<Value[\"data\"]>;\n\tdataRaw: Value[\"data\"];\n} & gatsby.NodeInput;\n\nexport const document = <Value extends prismicT.PrismicDocument>(\n\tconfig: NormalizeDocumentConfig<Value>,\n): NormalizedDocumentValue<Value> => {\n\tconst fields = {\n\t\t...config.value,\n\t\t__typename: config.nodeHelpers.createTypeName(config.path),\n\t\t_previewable: config.value.id,\n\t\talternate_languages: alternateLanguages({\n\t\t\t...config,\n\t\t\tvalue: config.value[\"alternate_languages\"],\n\t\t}),\n\t\turl: prismicH.asLink(config.value, config.linkResolver),\n\t\tdata: {},\n\t\tdataRaw: config.value.data,\n\t};\n\n\tif (Object.keys(config.value.data).length > 0) {\n\t\tfields.data = normalize({\n\t\t\t...config,\n\t\t\tvalue: config.value.data,\n\t\t\tpath: [...config.path, \"data\"],\n\t\t}) as NormalizedDocumentDataValue<Value[\"data\"]>;\n\t}\n\n\treturn config.nodeHelpers.createNodeFactory(config.value.type)(\n\t\tfields,\n\t) as NormalizedDocumentValue<Value>;\n};\n","import * as prismicT from \"@prismicio/types\";\n\nimport {\n\tNormalizeConfig,\n\tNormalizedValueMap,\n\tNormalizerDependencies,\n} from \"../types\";\nimport { normalize } from \"../normalize\";\n\nexport const isDocumentDataField = (\n\tvalue: unknown,\n): value is prismicT.PrismicDocument[\"data\"] => {\n\treturn typeof value === \"object\" && value !== null;\n};\n\ntype NormalizeDocumentDataConfig<\n\tValue extends prismicT.PrismicDocument[\"data\"],\n> = NormalizeConfig<Value> & NormalizerDependencies;\n\nexport type NormalizedDocumentDataValue<\n\tValue extends prismicT.PrismicDocument[\"data\"] = prismicT.PrismicDocument[\"data\"],\n> = NormalizedValueMap<Value>;\n\nexport const documentData = <Value extends prismicT.PrismicDocument[\"data\"]>(\n\tconfig: NormalizeDocumentDataConfig<Value>,\n): NormalizedDocumentDataValue<Value> => {\n\tconst result = {} as NormalizedDocumentDataValue<Value>;\n\n\tfor (const key in config.value) {\n\t\tconst transformedKey = config.transformFieldName(\n\t\t\tkey,\n\t\t) as keyof NormalizedDocumentDataValue<Value>;\n\n\t\tresult[transformedKey] = normalize({\n\t\t\t...config,\n\t\t\tvalue: config.value[key],\n\t\t\tpath: [...config.path, transformedKey as string],\n\t\t});\n\t}\n\n\treturn result;\n};\n","import * as prismicT from \"@prismicio/types\";\nimport { IterableElement } from \"type-fest\";\n\nimport {\n\tNormalizeConfig,\n\tNormalizedValueMap,\n\tNormalizerDependencies,\n} from \"../types\";\nimport { normalize } from \"../normalize\";\n\nexport const isGroupField = (value: unknown): value is prismicT.GroupField => {\n\treturn (\n\t\tArray.isArray(value) &&\n\t\tvalue.every((element) => typeof element === \"object\" && element !== null)\n\t);\n};\n\ntype NormalizeGroupConfig<Value extends prismicT.GroupField> =\n\tNormalizeConfig<Value> & NormalizerDependencies;\n\nexport type NormalizedGroupValue<\n\tValue extends prismicT.GroupField = prismicT.GroupField,\n> = NormalizedValueMap<IterableElement<Value>>[];\n\nexport const group = <Value extends prismicT.GroupField>(\n\tconfig: NormalizeGroupConfig<Value>,\n): NormalizedGroupValue<Value> => {\n\treturn config.value.map((element) => {\n\t\tconst result: NormalizedValueMap<typeof element> = {};\n\n\t\tfor (const key in element) {\n\t\t\tconst transformedKey = config.transformFieldName(key);\n\n\t\t\tresult[transformedKey] = normalize({\n\t\t\t\t...config,\n\t\t\t\tvalue: element[key],\n\t\t\t\tpath: [...config.path, transformedKey],\n\t\t\t});\n\t\t}\n\n\t\treturn result;\n\t}) as NormalizedGroupValue<Value>;\n};\n","/**\n * Sanitizes an image URL. The following steps are taken:\n *\n * - Replace `+` in filename with a space\n * - Decode the URL\n *\n * @param url - Image URL to sanitize.\n *\n * @returns Sanitized image URL.\n */\n// TODO: Remove once the Prismic API properly handles spaces in filenames\nexport const sanitizeImageURL = (url: string): string =>\n\tdecodeURIComponent(url.replace(/\\+/g, \" \"));\n","import * as O from \"fp-ts/Option\";\nimport { pipe } from \"fp-ts/function\";\n\n/**\n * Removes query parameters from a URL. If the URL is invalid, the input is\n * returned as is.\n *\n * @param url - URL from which to remove query parameters.\n *\n * @returns `url` without query parameters.\n */\nexport const stripURLQueryParameters = (url: string): string =>\n\tpipe(\n\t\tO.tryCatch(() => new URL(url)),\n\t\tO.map((instance) => `${instance.origin}${instance.pathname}`),\n\t\tO.getOrElse(() => url),\n\t);\n","import * as prismicT from \"@prismicio/types\";\nimport * as gatsbyImage from \"gatsby-image\";\nimport * as gatsbyPluginImage from \"gatsby-plugin-image\";\nimport * as imgixGatsby from \"@imgix/gatsby\";\nimport * as imgixGatsbyHelpers from \"@imgix/gatsby/dist/pluginHelpers.browser\";\n\nimport { sanitizeImageURL } from \"../../lib/sanitizeImageURL\";\nimport { stripURLQueryParameters } from \"../../lib/stripURLParameters\";\n\nimport { NormalizeConfig, NormalizerDependencies } from \"../types\";\nimport { PRISMIC_API_IMAGE_FIELDS } from \"../../constants\";\n\nconst getURLSearchParams = (url: string): Record<string, string> => {\n\tconst urlInstance = new URL(url);\n\tconst result: Record<string, string> = {};\n\n\tfor (const [key, value] of urlInstance.searchParams.entries()) {\n\t\tresult[key] = value;\n\t}\n\n\treturn result;\n};\n\nexport const isImageField = (value: unknown): value is prismicT.ImageField => {\n\t// Unfortunately, we can't check for specific properties here since it's\n\t// possible for the object to be empty if an image was never set.\n\treturn typeof value === \"object\" && value !== null;\n};\n\nexport type NormalizeImageConfig<\n\tValue extends prismicT.ImageField = prismicT.ImageField,\n> = NormalizeConfig<Value> &\n\tPick<\n\t\tNormalizerDependencies,\n\t\t\"imageImgixParams\" | \"imagePlaceholderImgixParams\"\n\t>;\n\ntype NormalizedImageBase<Value extends prismicT.ImageFieldImage> =\n\tValue extends prismicT.FilledImageFieldImage\n\t\t? Value & {\n\t\t\t\tfixed: gatsbyImage.FixedObject;\n\t\t\t\tfluid: gatsbyImage.FluidObject;\n\t\t\t\tgatsbyImageData: gatsbyPluginImage.IGatsbyImageData;\n\t\t\t\tlocalFile: {\n\t\t\t\t\tpublicURL: Value[\"url\"];\n\t\t\t\t\tchildImageSharp: {\n\t\t\t\t\t\tfixed: gatsbyImage.FixedObject;\n\t\t\t\t\t\tfluid: gatsbyImage.FluidObject;\n\t\t\t\t\t\tgatsbyImageData: gatsbyPluginImage.IGatsbyImageData;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t }\n\t\t: Value extends prismicT.EmptyImageFieldImage\n\t\t? Value & {\n\t\t\t\tfixed: null;\n\t\t\t\tfluid: null;\n\t\t\t\tgatsbyImageData: null;\n\t\t\t\tlocalFile: null;\n\t\t }\n\t\t: never;\n\nexport type NormalizedImageValue<Value extends prismicT.ImageField> =\n\tNormalizedImageBase<Value> & {\n\t\tthumbnails: Record<string, NormalizedImageBase<prismicT.ImageFieldImage>>;\n\t};\n\ntype BuildImageFieldConfig<Value extends prismicT.ImageFieldImage> = {\n\tvalue: Value;\n\timageImgixParams: imgixGatsby.ImgixUrlParams;\n\timagePlaceholderImgixParams: imgixGatsby.ImgixUrlParams;\n};\n\nconst buildImageField = <Value extends prismicT.ImageFieldImage>(\n\tconfig: BuildImageFieldConfig<Value>,\n): NormalizedImageBase<Value> => {\n\tif (config.value.url) {\n\t\tconst imgixParams = {\n\t\t\t...getURLSearchParams(config.value.url),\n\t\t\t...config.imageImgixParams,\n\t\t};\n\t\tconst placeholderImgixParams = config.imagePlaceholderImgixParams;\n\n\t\tconst url = new URL(config.value.url);\n\n\t\tconst normalizedURL = sanitizeImageURL(\n\t\t\tstripURLQueryParameters(url.toString()),\n\t\t);\n\n\t\tconst populatedUrl = new URL(url.toString());\n\t\tfor (const paramKey in imgixParams) {\n\t\t\tpopulatedUrl.searchParams.set(\n\t\t\t\tparamKey,\n\t\t\t\tString(imgixParams[paramKey as keyof typeof imgixParams]),\n\t\t\t);\n\t\t}\n\n\t\tconst fixed = imgixGatsbyHelpers.buildFixedObject({\n\t\t\turl: normalizedURL,\n\t\t\targs: {\n\t\t\t\twidth: 400,\n\t\t\t\timgixParams,\n\t\t\t\tplaceholderImgixParams,\n\t\t\t},\n\t\t\tsourceWidth: config.value.dimensions.width,\n\t\t\tsourceHeight: config.value.dimensions.height,\n\t\t});\n\n\t\tconst fluid = imgixGatsbyHelpers.buildFluidObject({\n\t\t\turl: normalizedURL,\n\t\t\targs: {\n\t\t\t\tmaxWidth: 800,\n\t\t\t\timgixParams,\n\t\t\t\tplaceholderImgixParams,\n\t\t\t},\n\t\t\tsourceWidth: config.value.dimensions.width,\n\t\t\tsourceHeight: config.value.dimensions.height,\n\t\t});\n\n\t\tconst gatsbyImageData = imgixGatsbyHelpers.buildGatsbyImageDataObject({\n\t\t\turl: normalizedURL,\n\t\t\tdimensions: config.value.dimensions,\n\t\t\tdefaultParams: imgixParams,\n\t\t\tresolverArgs: {},\n\t\t});\n\n\t\treturn {\n\t\t\turl: sanitizeImageURL(populatedUrl.toString()),\n\t\t\talt: config.value.alt,\n\t\t\tcopyright: config.value.copyright,\n\t\t\tdimensions: config.value.dimensions,\n\t\t\tfixed,\n\t\t\tfluid,\n\t\t\tgatsbyImageData,\n\t\t\tlocalFile: {\n\t\t\t\tpublicURL: config.value.url,\n\t\t\t\tchildImageSharp: {\n\t\t\t\t\tfixed,\n\t\t\t\t\tfluid,\n\t\t\t\t\tgatsbyImageData,\n\t\t\t\t},\n\t\t\t},\n\t\t} as NormalizedImageBase<Value>;\n\t} else {\n\t\treturn {\n\t\t\turl: null,\n\t\t\talt: null,\n\t\t\tcopyright: null,\n\t\t\tdimensions: null,\n\t\t\tfixed: null,\n\t\t\tgatsbyImageData: null,\n\t\t\tfluid: null,\n\t\t\tlocalFile: null,\n\t\t} as NormalizedImageBase<Value>;\n\t}\n};\n\nexport const image = <Value extends prismicT.ImageField<string>>(\n\tconfig: NormalizeImageConfig<Value>,\n): NormalizedImageValue<Value> => {\n\tconst result = {\n\t\t...buildImageField({\n\t\t\tvalue: config.value,\n\t\t\timageImgixParams: config.imageImgixParams,\n\t\t\timagePlaceholderImgixParams: config.imagePlaceholderImgixParams,\n\t\t}),\n\t\tthumbnails: {},\n\t} as NormalizedImageValue<Value>;\n\n\tconst thumbnailNames = Object.keys(config.value).filter(\n\t\t(key) => !PRISMIC_API_IMAGE_FIELDS.includes(key),\n\t);\n\n\tfor (const thumbnailName of thumbnailNames) {\n\t\tresult.thumbnails[thumbnailName as keyof typeof result.thumbnails] =\n\t\t\tbuildImageField({\n\t\t\t\tvalue: config.value[thumbnailName as keyof typeof config.value],\n\t\t\t\timageImgixParams: config.imageImgixParams,\n\t\t\t\timagePlaceholderImgixParams: config.imagePlaceholderImgixParams,\n\t\t\t});\n\t}\n\n\treturn result;\n};\n","import * as prismicT from \"@prismicio/types\";\nimport * as prismicH from \"@prismicio/helpers\";\n\nimport { PrismicDocumentNodeInput } from \"../../types\";\n\nimport { createGetProxy } from \"../createGetProxy\";\nimport { NormalizeConfig, NormalizerDependencies } from \"../types\";\n\nexport const isLinkField = (value: unknown): value is prismicT.LinkField => {\n\treturn typeof value === \"object\" && (value === null || \"link_type\" in value);\n};\n\nexport type NormalizeLinkConfig<\n\tValue extends prismicT.LinkField = prismicT.LinkField,\n> = NormalizeConfig<Value> &\n\tPick<NormalizerDependencies, \"linkResolver\" | \"getNode\">;\n\nexport type NormalizedLinkValue<Value extends prismicT.LinkField> = Value & {\n\turl?: string | null;\n\traw: Value;\n\tdocument?: PrismicDocumentNodeInput | null;\n\tlocalFile?: {\n\t\tpublicURL: string;\n\t};\n};\n\nexport const link = <Value extends prismicT.LinkField>(\n\tconfig: NormalizeLinkConfig<Value>,\n): NormalizedLinkValue<Value> => {\n\tconst value: NormalizedLinkValue<Value> = {\n\t\t...config.value,\n\t\turl: prismicH.asLink(config.value, config.linkResolver),\n\t\tlocalFile: undefined,\n\t\traw: config.value,\n\t};\n\n\tif (\n\t\tconfig.value.link_type === prismicT.LinkType.Media &&\n\t\t\"url\" in config.value\n\t) {\n\t\tvalue.localFile = {\n\t\t\tpublicURL: config.value.url,\n\t\t};\n\t}\n\n\treturn createGetProxy(value, (target, prop, receiver) => {\n\t\tif (\n\t\t\tprop === \"document\" &&\n\t\t\tconfig.value.link_type === prismicT.LinkType.Document &&\n\t\t\t\"id\" in config.value &&\n\t\t\t!config.value.isBroken\n\t\t) {\n\t\t\treturn config.getNode(config.value.id) || null;\n\t\t}\n\n\t\treturn Reflect.get(target, prop, receiver);\n\t});\n};\n","import * as prismicH from \"@prismicio/helpers\";\n\nimport {\n\tNormalizeConfig,\n\tNormalizerDependencies,\n\tStructuredTextField,\n} from \"../types\";\n\nexport const isStructuredTextField = (\n\tvalue: unknown,\n): value is StructuredTextField => {\n\t// We must be very loose here. An image element, for example, does not\n\t// contain a `text` property.\n\treturn Array.isArray(value) && value.every((element) => \"type\" in element);\n};\n\nexport type NormalizeStructuredTextConfig<\n\tValue extends StructuredTextField = StructuredTextField,\n> = NormalizeConfig<Value> &\n\tPick<NormalizerDependencies, \"linkResolver\" | \"htmlSerializer\">;\n\nexport type NormalizedStructuredTextValue<Value extends StructuredTextField> = {\n\thtml: string;\n\ttext: string;\n\trichText: Value;\n\traw: Value;\n};\n\nexport const structuredText = <Value extends StructuredTextField>(\n\tconfig: NormalizeStructuredTextConfig<Value>,\n): NormalizedStructuredTextValue<Value> => {\n\treturn {\n\t\thtml: prismicH.asHTML(\n\t\t\tconfig.value,\n\t\t\tconfig.linkResolver,\n\t\t\tconfig.htmlSerializer,\n\t\t),\n\t\ttext: prismicH.asText(config.value),\n\t\trichText: config.value,\n\t\traw: config.value,\n\t};\n};\n","import * as prismicT from \"@prismicio/types\";\nimport { IterableElement } from \"type-fest\";\n\nimport {\n\tNormalizeConfig,\n\tNormalizedValueMap,\n\tNormalizerDependencies,\n} from \"../types\";\nimport { normalize } from \"../normalize\";\n\nexport const isSlice = (\n\tvalue: unknown,\n): value is prismicT.Slice | prismicT.SharedSlice => {\n\treturn typeof value === \"object\" && value !== null && \"slice_type\" in value;\n};\n\nexport const isSharedSlice = (\n\tvalue: prismicT.Slice,\n): value is prismicT.SharedSlice => \"variation\" in value;\n\nexport type NormalizeSliceConfig<Value extends prismicT.Slice> =\n\tNormalizeConfig<Value> & NormalizerDependencies;\n\nexport type NormalizedSliceValue<\n\tValue extends prismicT.Slice | prismicT.SharedSlice =\n\t\t| prismicT.Slice\n\t\t| prismicT.SharedSlice,\n> = Value extends prismicT.SharedSlice\n\t? {\n\t\t\t__typename: string;\n\t\t\tid: string;\n\t\t\tslice_type: Value[\"slice_type\"];\n\t\t\tslice_label: Value[\"slice_label\"];\n\t\t\tvariation: string;\n\t\t\tversion: string;\n\t\t\tprimary: NormalizedValueMap<Value[\"primary\"]>;\n\t\t\titems: NormalizedValueMap<IterableElement<Value[\"items\"]>>[];\n\t }\n\t: {\n\t\t\t__typename: string;\n\t\t\tid: string;\n\t\t\tslice_type: Value[\"slice_type\"];\n\t\t\tslice_label: Value[\"slice_label\"];\n\t\t\tprimary: NormalizedValueMap<Value[\"primary\"]>;\n\t\t\titems: NormalizedValueMap<IterableElement<Value[\"items\"]>>[];\n\t };\n\nexport const slice = <Value extends prismicT.Slice | prismicT.SharedSlice>(\n\tconfig: NormalizeSliceConfig<Value>,\n): NormalizedSliceValue<Value> => {\n\tconst { primary, items, ...value } = config.value;\n\n\tconst result = {\n\t\t...value,\n\t\t__typename: config.nodeHelpers.createTypeName(config.path),\n\t\tid: config.nodeHelpers.createNodeId([\n\t\t\t...config.path,\n\t\t\tJSON.stringify(config.value),\n\t\t]),\n\t\tslice_type: config.value.slice_type,\n\t\tslice_label: config.value.slice_label,\n\t} as unknown as NormalizedSliceValue<Value>;\n\t// Yes, using `as unknown as X` is bad practice.\n\t// Yes, you can fix this if you know how to do it.\n\t// Yes, that means you!\n\n\tresult.primary = {} as NormalizedSliceValue[\"primary\"];\n\n\tfor (const key in primary) {\n\t\tconst transformedKey = config.transformFieldName(\n\t\t\tkey,\n\t\t) as keyof NormalizedSliceValue[\"primary\"];\n\n\t\tresult.primary[transformedKey] = normalize({\n\t\t\t...config,\n\t\t\tvalue: config.value.primary[key],\n\t\t\tpath: [...config.path, \"primary\", transformedKey],\n\t\t});\n\t}\n\n\tresult.items = items.map((item) => {\n\t\tconst result = {} as IterableElement<NormalizedSliceValue[\"items\"]>;\n\n\t\tfor (const key in item) {\n\t\t\tconst transformedKey = config.transformFieldName(\n\t\t\t\tkey,\n\t\t\t) as keyof IterableElement<NormalizedSliceValue[\"items\"]>;\n\n\t\t\tresult[transformedKey] = normalize({\n\t\t\t\t...config,\n\t\t\t\tvalue: item[key],\n\t\t\t\tpath: [...config.path, \"items\", transformedKey],\n\t\t\t});\n\t\t}\n\n\t\treturn result;\n\t});\n\n\treturn result;\n};\n","import * as prismicT from \"@prismicio/types\";\nimport { IterableElement, Simplify } from \"type-fest\";\n\nimport {\n\tNormalizeConfig,\n\tNormalizedValue,\n\tNormalizerDependencies,\n} from \"../types\";\nimport { normalize } from \"../normalize\";\nimport { isSharedSlice, isSlice } from \"./slice\";\n\nexport const isSlices = (value: unknown): value is prismicT.SliceZone => {\n\treturn Array.isArray(value) && value.every((element) => isSlice(element));\n};\n\ntype NormalizeSlicesConfig<Value extends prismicT.SliceZone> =\n\tNormalizeConfig<Value> & NormalizerDependencies;\n\nexport type NormalizedSlicesValue<\n\tValue extends prismicT.SliceZone = prismicT.SliceZone,\n> = NormalizedValue<Simplify<IterableElement<Value>>>[];\n\nexport const slices = <Value extends prismicT.SliceZone>(\n\tconfig: NormalizeSlicesConfig<Value>,\n): NormalizedSlicesValue<Value> => {\n\treturn config.value.map((element) => {\n\t\treturn normalize({\n\t\t\t...config,\n\t\t\tvalue: element,\n\t\t\tpath: isSharedSlice(element)\n\t\t\t\t? [element.slice_type, element.variation]\n\t\t\t\t: [...config.path, element.slice_type],\n\t\t});\n\t}) as NormalizedSlicesValue<Value>;\n};\n","import * as prismicT from \"@prismicio/types\";\n\nimport { PrismicSpecialType } from \"../types\";\n\nimport * as normalizers from \"./normalizers\";\nimport {\n\tNormalizedValue,\n\tStructuredTextField,\n\tNormalizeConfig as BaseNormalizeConfig,\n\tNormalizerDependencies,\n} from \"./types\";\n\nfunction assertType<T>(\n\ttype:\n\t\t| prismicT.CustomTypeModelFieldType\n\t\t| prismicT.CustomTypeModelSliceType\n\t\t| PrismicSpecialType,\n\tguard: (value: unknown) => boolean,\n\tvalue: unknown,\n): asserts value is T {\n\tif (!guard(value)) {\n\t\tthrow new Error(`Value is not expected type ${type}`);\n\t}\n}\n\ntype NormalizeConfig<Value> = BaseNormalizeConfig<Value> &\n\tNormalizerDependencies;\n\nexport const normalize = <Value>(\n\tconfig: NormalizeConfig<Value>,\n): NormalizedValue<Value> => {\n\tconst type = config.getTypePath(config.path);\n\tif (!type) {\n\t\tthrow new Error(\n\t\t\t`No type for path: ${config.path.join(\n\t\t\t\t\".\",\n\t\t\t)}. Did you register the Custom Type model?`,\n\t\t);\n\t}\n\n\tswitch (type.type) {\n\t\tcase PrismicSpecialType.Document: {\n\t\t\tassertType<prismicT.PrismicDocument>(\n\t\t\t\tPrismicSpecialType.Document,\n\t\t\t\tnormalizers.isDocument,\n\t\t\t\tconfig.value,\n\t\t\t);\n\n\t\t\treturn normalizers.document({\n\t\t\t\t...config,\n\t\t\t\tvalue: config.value,\n\t\t\t}) as NormalizedValue<Value>;\n\t\t}\n\n\t\tcase PrismicSpecialType.DocumentData: {\n\t\t\tassertType<prismicT.PrismicDocument[\"data\"]>(\n\t\t\t\tPrismicSpecialType.DocumentData,\n\t\t\t\tnormalizers.isDocumentDataField,\n\t\t\t\tconfig.value,\n\t\t\t);\n\n\t\t\treturn normalizers.documentData({\n\t\t\t\t...config,\n\t\t\t\tvalue: config.value,\n\t\t\t}) as NormalizedValue<Value>;\n\t\t}\n\n\t\tcase prismicT.CustomTypeModelFieldType.Group: {\n\t\t\tassertType<prismicT.GroupField>(\n\t\t\t\tprismicT.CustomTypeModelFieldType.Group,\n\t\t\t\tnormalizers.isGroupField,\n\t\t\t\tconfig.value,\n\t\t\t);\n\n\t\t\treturn normalizers.group({\n\t\t\t\t...config,\n\t\t\t\tvalue: config.value,\n\t\t\t}) as NormalizedValue<Value>;\n\t\t}\n\n\t\tcase prismicT.CustomTypeModelFieldType.Slices: {\n\t\t\tassertType<prismicT.SliceZone>(\n\t\t\t\tprismicT.CustomTypeModelFieldType.Slices,\n\t\t\t\tnormalizers.isSlices,\n\t\t\t\tconfig.value,\n\t\t\t);\n\n\t\t\treturn normalizers.slices({\n\t\t\t\t...config,\n\t\t\t\tvalue: config.value,\n\t\t\t}) as NormalizedValue<Value>;\n\t\t}\n\n\t\tcase prismicT.CustomTypeModelSliceType.Slice:\n\t\tcase PrismicSpecialType.SharedSliceVariation: {\n\t\t\tassertType<prismicT.Slice | prismicT.SharedSlice>(\n\t\t\t\tprismicT.CustomTypeModelSliceType.Slice,\n\t\t\t\tnormalizers.isSlice,\n\t\t\t\tconfig.value,\n\t\t\t);\n\n\t\t\treturn normalizers.slice({\n\t\t\t\t...config,\n\t\t\t\tvalue: config.value,\n\t\t\t}) as NormalizedValue<Value>;\n\t\t}\n\n\t\tcase prismicT.CustomTypeModelFieldType.Link: {\n\t\t\tassertType<prismicT.LinkField>(\n\t\t\t\tprismicT.CustomTypeModelFieldType.Link,\n\t\t\t\tnormalizers.isLinkField,\n\t\t\t\tconfig.value,\n\t\t\t);\n\n\t\t\treturn normalizers.link({\n\t\t\t\tvalue: config.value,\n\t\t\t\tpath: config.path,\n\t\t\t\tgetNode: config.getNode,\n\t\t\t\tlinkResolver: config.linkResolver,\n\t\t\t}) as NormalizedValue<Value>;\n\t\t}\n\n\t\tcase prismicT.CustomTypeModelFieldType.Image: {\n\t\t\tassertType<prismicT.ImageField>(\n\t\t\t\tprismicT.CustomTypeModelFieldType.Image,\n\t\t\t\tnormalizers.isImageField,\n\t\t\t\tconfig.value,\n\t\t\t);\n\n\t\t\treturn normalizers.image({\n\t\t\t\tvalue: config.value,\n\t\t\t\tpath: config.path,\n\t\t\t\timageImgixParams: config.imageImgixParams,\n\t\t\t\timagePlaceholderImgixParams: config.imagePlaceholderImgixParams,\n\t\t\t}) as NormalizedValue<Value>;\n\t\t}\n\n\t\tcase prismicT.CustomTypeModelFieldType.StructuredText: {\n\t\t\tassertType<StructuredTextField>(\n\t\t\t\tprismicT.CustomTypeModelFieldType.StructuredText,\n\t\t\t\tnormalizers.isStructuredTextField,\n\t\t\t\tconfig.value,\n\t\t\t);\n\n\t\t\treturn normalizers.structuredText({\n\t\t\t\tvalue: config.value,\n\t\t\t\tpath: config.path,\n\t\t\t\tlinkResolver: config.linkResolver,\n\t\t\t\thtmlSerializer: config.htmlSerializer,\n\t\t\t}) as NormalizedValue<Value>;\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn config.value as NormalizedValue<Value>;\n\t\t}\n\t}\n};\n","import * as prismicT from \"@prismicio/types\";\n\nimport {\n\tPrismicSpecialType,\n\tTransformFieldNameFn,\n\tTypePath,\n\tTypePathKind,\n} from \"../types\";\n\nconst fieldToTypePaths = <\n\tModel extends prismicT.CustomTypeModelField | prismicT.CustomTypeModelSlice,\n>(\n\tpath: string[],\n\tmodel: Model,\n\ttransformFieldName: TransformFieldNameFn,\n): TypePath[] => {\n\tswitch (model.type) {\n\t\tcase prismicT.CustomTypeModelFieldType.UID: {\n\t\t\treturn [];\n\t\t}\n\n\t\tcase prismicT.CustomTypeModelFieldType.Group: {\n\t\t\tconst fields = Object.entries(model.config.fields).flatMap(\n\t\t\t\t([fieldId, fieldModel]) =>\n\t\t\t\t\tfieldToTypePaths(\n\t\t\t\t\t\t[...path, transformFieldName(fieldId)],\n\t\t\t\t\t\tfieldModel,\n\t\t\t\t\t\ttransformFieldName,\n\t\t\t\t\t),\n\t\t\t);\n\n\t\t\treturn [{ kind: TypePathKind.Field, type: model.type, path }, ...fields];\n\t\t}\n\n\t\tcase prismicT.CustomTypeModelFieldType.Slices: {\n\t\t\tconst choices = (\n\t\t\t\t(model.config.choices && Object.entries(model.config.choices)) ||\n\t\t\t\t[]\n\t\t\t)\n\t\t\t\t.filter(\n\t\t\t\t\t(entry): entry is [string, prismicT.CustomTypeModelSlice] =>\n\t\t\t\t\t\tentry[1].type === prismicT.CustomTypeModelSliceType.Slice,\n\t\t\t\t)\n\t\t\t\t.flatMap(([choiceId, choiceModel]) =>\n\t\t\t\t\tfieldToTypePaths(\n\t\t\t\t\t\t[...path, choiceId],\n\t\t\t\t\t\tchoiceModel,\n\t\t\t\t\t\ttransformFieldName,\n\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\treturn [{ kind: TypePathKind.Field, type: model.type, path }, ...choices];\n\t\t}\n\n\t\tcase prismicT.CustomTypeModelSliceType.Slice: {\n\t\t\tconst primary = Object.entries(model[\"non-repeat\"] || {}).flatMap(\n\t\t\t\t([fieldId, fieldModel]) =>\n\t\t\t\t\tfieldToTypePaths(\n\t\t\t\t\t\t[...path, \"primary\", transformFieldName(fieldId)],\n\t\t\t\t\t\tfieldModel,\n\t\t\t\t\t\ttransformFieldName,\n\t\t\t\t\t),\n\t\t\t);\n\n\t\t\tconst items = Object.entries(model.repeat || {}).flatMap(\n\t\t\t\t([fieldId, fieldModel]) =>\n\t\t\t\t\tfieldToTypePaths(\n\t\t\t\t\t\t[...path, \"items\", transformFieldName(fieldId)],\n\t\t\t\t\t\tfieldModel,\n\t\t\t\t\t\ttransformFieldName,\n\t\t\t\t\t),\n\t\t\t);\n\n\t\t\treturn [\n\t\t\t\t{ kind: TypePathKind.Field, type: model.type, path },\n\t\t\t\t...primary,\n\t\t\t\t...items,\n\t\t\t];\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkind: TypePathKind.Field,\n\t\t\t\t\tpath,\n\t\t\t\t\ttype: model.type,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t}\n};\n\nexport const customTypeModelToTypePaths = <\n\tModel extends prismicT.CustomTypeModel,\n>(\n\tcustomTypeModel: Model,\n\ttransformFieldName: TransformFieldNameFn,\n): TypePath[] => {\n\tconst definition = customTypeModel.json;\n\tconst fieldModels = Object.assign({}, ...Object.values(definition)) as Record<\n\t\tstring,\n\t\tprismicT.CustomTypeModelField\n\t>;\n\n\tconst hasDataFields =\n\t\tObject.values(fieldModels).filter(\n\t\t\t(fieldModel) => fieldModel.type !== prismicT.CustomTypeModelFieldType.UID,\n\t\t).length > 0;\n\n\tconst documentTypePath = {\n\t\tkind: TypePathKind.CustomType,\n\t\ttype: PrismicSpecialType.Document,\n\t\tpath: [customTypeModel.id],\n\t};\n\n\tif (hasDataFields) {\n\t\tconst data = Object.entries(fieldModels).flatMap(([fieldId, fieldModel]) =>\n\t\t\tfieldToTypePaths(\n\t\t\t\t[customTypeModel.id, \"data\", transformFieldName(fieldId)],\n\t\t\t\tfieldModel,\n\t\t\t\ttransformFieldName,\n\t\t\t),\n\t\t);\n\n\t\treturn [\n\t\t\tdocumentTypePath,\n\t\t\t{\n\t\t\t\tkind: TypePathKind.Field,\n\t\t\t\ttype: PrismicSpecialType.DocumentData,\n\t\t\t\tpath: [customTypeModel.id, \"data\"],\n\t\t\t},\n\t\t\t...data,\n\t\t];\n\t} else {\n\t\treturn [documentTypePath];\n\t}\n};\n\nexport const sharedSliceModelToTypePaths = <\n\tModel extends prismicT.SharedSliceModel,\n>(\n\tsharedSliceModel: Model,\n\ttransformFieldName: TransformFieldNameFn,\n): TypePath[] => {\n\treturn sharedSliceModel.variations.flatMap((variation) => {\n\t\tconst primary = Object.entries(variation.primary || {}).flatMap(\n\t\t\t([fieldId, fieldModel]) =>\n\t\t\t\tfieldToTypePaths(\n\t\t\t\t\t[\n\t\t\t\t\t\tsharedSliceModel.id,\n\t\t\t\t\t\tvariation.id,\n\t\t\t\t\t\t\"primary\",\n\t\t\t\t\t\ttransformFieldName(fieldId),\n\t\t\t\t\t],\n\t\t\t\t\tfieldModel,\n\t\t\t\t\ttransformFieldName,\n\t\t\t\t),\n\t\t);\n\n\t\tconst items = Object.entries(variation.items || {}).flatMap(\n\t\t\t([fieldId, fieldModel]) =>\n\t\t\t\tfieldToTypePaths(\n\t\t\t\t\t[\n\t\t\t\t\t\tsharedSliceModel.id,\n\t\t\t\t\t\tvariation.id,\n\t\t\t\t\t\t\"items\",\n\t\t\t\t\t\ttransformFieldName(fieldId),\n\t\t\t\t\t],\n\t\t\t\t\tfieldModel,\n\t\t\t\t\ttransformFieldName,\n\t\t\t\t),\n\t\t);\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: TypePathKind.SharedSliceVariation,\n\t\t\t\ttype: PrismicSpecialType.SharedSliceVariation,\n\t\t\t\tpath: [sharedSliceModel.id, variation.id],\n\t\t\t},\n\t\t\t...primary,\n\t\t\t...items,\n\t\t];\n\t});\n};\n","export const serializePath = (path: string[]): string => path.join(\".\");\n","import { SerializedTypePath, TypePath } from \"../types\";\nimport { serializePath } from \"./serializePath\";\n\nexport const serializeTypePaths = (\n\ttypePaths: TypePath[],\n): SerializedTypePath[] => {\n\treturn typePaths.map((typePath) => {\n\t\treturn {\n\t\t\t...typePath,\n\t\t\tpath: serializePath(typePath.path),\n\t\t};\n\t});\n};\n","import * as prismicT from \"@prismicio/types\";\nimport * as prismicH from \"@prismicio/helpers\";\nimport * as imgixGatsby from \"@imgix/gatsby\";\nimport * as nodeHelpers from \"gatsby-node-helpers\";\nimport { pipe } from \"fp-ts/function\";\n\nimport { SerializedTypePath, TransformFieldNameFn, TypePath } from \"../types\";\nimport { normalize } from \"./normalize\";\nimport {\n\tDEFAULT_IMGIX_PARAMS,\n\tDEFAULT_PLACEHOLDER_IMGIX_PARAMS,\n\tGLOBAL_TYPE_PREFIX,\n} from \"../constants\";\nimport { NormalizedValue } from \"./types\";\nimport { SetRequired } from \"type-fest\";\nimport {\n\tcustomTypeModelToTypePaths,\n\tsharedSliceModelToTypePaths,\n} from \"./typePaths\";\nimport { NormalizedDocumentValue } from \"./normalizers\";\nimport { serializeTypePaths } from \"./serializeTypePaths\";\nimport { serializePath } from \"./serializePath\";\n\n// `createNodeId` would normally create a hash from its input, but we can treat\n// it as an identity function since we are using it within the context of\n// Prismic documents with unique IDs.\nconst createNodeId = (input: string): string => input;\n\n// `createContentDigest` would normally create a hash from its input, but we\n// can treat it as a stubbed function since a Gatsby node's\n// `internal.contentDigest` property is an internal field. In a runtime\n// preview, we don't need the digest.\nconst createContentDigest = <T>(_input: T): string =>\n\t\"contentDigest is not supported during previews\";\n\nexport type RuntimeConfig = {\n\ttypePrefix?: string;\n\tlinkResolver?: prismicH.LinkResolverFunction;\n\timageImgixParams?: imgixGatsby.ImgixUrlParams;\n\timagePlaceholderImgixParams?: imgixGatsby.ImgixUrlParams;\n\thtmlSerializer?: prismicH.HTMLMapSerializer | prismicH.HTMLFunctionSerializer;\n\ttransformFieldName?: TransformFieldNameFn;\n};\n\ntype SubscriberFn = () => void;\n\nexport const createRuntime = (config: RuntimeConfig = {}): Runtime => {\n\treturn new Runtime(config);\n};\n\nexport class Runtime {\n\tnodes: NormalizedDocumentValue[];\n\ttypePaths: SerializedTypePath[];\n\tsubscribers: SubscriberFn[];\n\n\tconfig: SetRequired<\n\t\tRuntimeConfig,\n\t\t\"imageImgixParams\" | \"imagePlaceholderImgixParams\" | \"transformFieldName\"\n\t>;\n\n\tnodeHelpers: nodeHelpers.NodeHelpers;\n\n\tconstructor(config: RuntimeConfig = {}) {\n\t\tthis.nodes = [];\n\t\tthis.typePaths = [];\n\t\tthis.subscribers = [];\n\n\t\tthis.config = {\n\t\t\t...config,\n\t\t\timageImgixParams: config.imageImgixParams ?? DEFAULT_IMGIX_PARAMS,\n\t\t\timagePlaceholderImgixParams:\n\t\t\t\tconfig.imagePlaceholderImgixParams ?? DEFAULT_PLACEHOLDER_IMGIX_PARAMS,\n\t\t\ttransformFieldName:\n\t\t\t\tconfig.transformFieldName ??\n\t\t\t\t((fieldName: string) => fieldName.replace(/-/g, \"_\")),\n\t\t};\n\n\t\tthis.nodeHelpers = nodeHelpers.createNodeHelpers({\n\t\t\ttypePrefix: [GLOBAL_TYPE_PREFIX, config.typePrefix]\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(\" \"),\n\t\t\tfieldPrefix: GLOBAL_TYPE_PREFIX,\n\t\t\tcreateNodeId,\n\t\t\tcreateContentDigest,\n\t\t});\n\t}\n\n\tsubscribe(callback: SubscriberFn): void {\n\t\tthis.subscribers = [...this.subscribers, callback];\n\t}\n\n\tunsubscribe(callback: SubscriberFn): void {\n\t\tthis.subscribers = this.subscribers.filter(\n\t\t\t(registeredCallback) => registeredCallback !== callback,\n\t\t);\n\t}\n\n\tregisterCustomTypeModel(\n\t\tmodel: prismicT.CustomTypeModel,\n\t): SerializedTypePath[] {\n\t\tconst typePaths = pipe(\n\t\t\tcustomTypeModelToTypePaths(model, this.config.transformFieldName),\n\t\t\tserializeTypePaths,\n\t\t);\n\n\t\tthis.typePaths = [...this.typePaths, ...typePaths];\n\n\t\tthis.#notifySubscribers();\n\n\t\treturn typePaths;\n\t}\n\n\tregisterCustomTypeModels(\n\t\tmodels: prismicT.CustomTypeModel[],\n\t): SerializedTypePath[] {\n\t\tconst typePaths = pipe(\n\t\t\tmodels.flatMap((model) =>\n\t\t\t\tcustomTypeModelToTypePaths(model, this.config.transformFieldName),\n\t\t\t),\n\t\t\tserializeTypePaths,\n\t\t);\n\n\t\tthis.typePaths = [...this.typePaths, ...typePaths];\n\n\t\tthis.#notifySubscribers();\n\n\t\treturn typePaths;\n\t}\n\n\tregisterSharedSliceModel(\n\t\tmodel: prismicT.SharedSliceModel,\n\t): SerializedTypePath[] {\n\t\tconst typePaths = pipe(\n\t\t\tsharedSliceModelToTypePaths(model, this.config.transformFieldName),\n\t\t\tserializeTypePaths,\n\t\t);\n\n\t\tthis.typePaths = [...this.typePaths, ...typePaths];\n\n\t\tthis.#notifySubscribers();\n\n\t\treturn typePaths;\n\t}\n\n\tregisterSharedSliceModels(\n\t\tmodels: prismicT.SharedSliceModel[],\n\t): SerializedTypePath[] {\n\t\tconst typePaths = pipe(\n\t\t\tmodels.flatMap((model) =>\n\t\t\t\tsharedSliceModelToTypePaths(model, this.config.transformFieldName),\n\t\t\t),\n\t\t\tserializeTypePaths,\n\t\t);\n\n\t\tthis.typePaths = [...this.typePaths, ...typePaths];\n\n\t\tthis.#notifySubscribers();\n\n\t\treturn typePaths;\n\t}\n\n\tregisterDocument<PrismicDocument extends prismicT.PrismicDocument>(\n\t\tdocument: PrismicDocument,\n\t): NormalizedDocumentValue<PrismicDocument> {\n\t\tconst normalizedDocument = this.normalizeDocument(document);\n\n\t\tthis.nodes = [...this.nodes, normalizedDocument];\n\n\t\tthis.#notifySubscribers();\n\n\t\treturn normalizedDocument;\n\t}\n\n\tregisterDocuments<PrismicDocument extends prismicT.PrismicDocument>(\n\t\tdocuments: PrismicDocument[],\n\t): NormalizedDocumentValue<PrismicDocument>[] {\n\t\tconst nodes = documents.map((document) => {\n\t\t\treturn this.normalizeDocument(document);\n\t\t});\n\n\t\tthis.nodes = [...this.nodes, ...nodes];\n\n\t\tthis.#notifySubscribers();\n\n\t\treturn nodes;\n\t}\n\n\tnormalizeDocument<PrismicDocument extends prismicT.PrismicDocument>(\n\t\tdocument: PrismicDocument,\n\t): NormalizedDocumentValue<PrismicDocument> {\n\t\treturn this.normalize(document, [\n\t\t\tdocument.type,\n\t\t]) as NormalizedDocumentValue<PrismicDocument>;\n\t}\n\n\tnormalize<Value>(value: Value, path: string[]): NormalizedValue<Value> {\n\t\treturn normalize({\n\t\t\tvalue,\n\t\t\tpath,\n\t\t\tgetNode: this.getNode.bind(this),\n\t\t\tgetTypePath: this.getTypePath.bind(this),\n\t\t\tnodeHelpers: this.nodeHelpers,\n\t\t\tlinkResolver: this.config.linkResolver,\n\t\t\thtmlSerializer: this.config.htmlSerializer,\n\t\t\timageImgixParams: this.config.imageImgixParams,\n\t\t\timagePlaceholderImgixParams: this.config.imagePlaceholderImgixParams,\n\t\t\ttransformFieldName: this.config.transformFieldName,\n\t\t});\n\t}\n\n\tgetNode<Document extends prismicT.PrismicDocument>(\n\t\tid: string,\n\t): NormalizedDocumentValue<Document> | undefined {\n\t\treturn this.nodes.find(\n\t\t\t(node): node is NormalizedDocumentValue<Document> =>\n\t\t\t\tnode.prismicId === id,\n\t\t);\n\t}\n\n\thasNode(id: string): boolean {\n\t\treturn this.nodes.some((node) => node.prismicId === id);\n\t}\n\n\tgetTypePath(path: string[]): SerializedTypePath | undefined {\n\t\treturn this.typePaths.find(\n\t\t\t(typePath) => typePath.path === serializePath(path),\n\t\t);\n\t}\n\n\texportTypePaths(): string {\n\t\treturn JSON.stringify(this.typePaths);\n\t}\n\n\timportTypePaths(typePathsExport: string): TypePath[] {\n\t\tconst importedTypePaths = JSON.parse(typePathsExport);\n\n\t\tthis.typePaths = [...this.typePaths, ...importedTypePa