gatsby-source-prismic
Version:
Gatsby source plugin for building websites using Prismic as a data source
132 lines (127 loc) • 3.52 kB
text/typescript
import * as gatsby from "gatsby";
import * as prismicT from "@prismicio/types";
import * as RTE from "fp-ts/ReaderTaskEither";
import * as R from "fp-ts/Record";
import * as ReadonlyA from "fp-ts/ReadonlyArray";
import { pipe, flow, identity } from "fp-ts/function";
import { buildObjectType } from "../lib/buildObjectType";
import { buildSchemaRecordType } from "../lib/buildSchemaRecordType";
import { getTypeName } from "../lib/getTypeName";
import { listTypeName } from "../lib/listTypeName";
import { createTypes } from "../lib/createTypes";
import { Dependencies, Mutable, UnknownRecord } from "../types";
import { requiredTypeName } from "../lib/requiredTypeName";
/**
* @returns GraphQL object type.
*/
const buildSharedSliceVariationType = (
path: string[],
variationModel: prismicT.SharedSliceModelVariation,
): RTE.ReaderTaskEither<Dependencies, Error, gatsby.GatsbyGraphQLObjectType> =>
pipe(
RTE.ask<Dependencies>(),
RTE.chain((deps) =>
pipe(
{} as Record<
"primary" | "items",
RTE.ReaderTaskEither<
Dependencies,
never,
gatsby.GatsbyGraphQLObjectType
>
>,
R.isEmpty(variationModel.primary)
? identity
: R.upsertAt(
"primary",
buildSchemaRecordType(
[...path, variationModel.id, "primary"],
variationModel.primary,
),
),
R.isEmpty(variationModel.items)
? identity
: R.upsertAt(
"items",
buildSchemaRecordType(
[...path, variationModel.id, "items"],
variationModel.items,
[...path, variationModel.id, "item"],
),
),
R.sequence(RTE.ApplicativeSeq),
RTE.chainFirstW(
flow(
R.collect((_, type) => type),
createTypes,
),
),
RTE.map(
R.mapWithIndex((field, type) =>
field === "items"
? pipe(
type,
getTypeName,
requiredTypeName,
listTypeName,
requiredTypeName,
)
: pipe(type, getTypeName, requiredTypeName),
),
),
RTE.chainW((fields) =>
buildObjectType({
name: deps.nodeHelpers.createTypeName([...path, variationModel.id]),
fields: {
...fields,
id: {
type: "ID!",
resolve: (source: UnknownRecord): string =>
deps.nodeHelpers.createNodeId([
...path,
variationModel.id,
deps.createContentDigest(source),
]),
},
slice_type: "String!",
slice_label: "String",
version: "String!",
variation: "String!",
},
interfaces: [
deps.globalNodeHelpers.createTypeName("SliceType"),
deps.globalNodeHelpers.createTypeName("SharedSliceType"),
],
extensions: { infer: false },
}),
),
),
),
);
/**
* Builds GraphQL types for a Shared Slice's variations. The resulting types can
* be created using Gatsby's `createTypes` action.
*
* @param path - Path to the Shared Slice.
* @param variations - List of Shared Slice variations.
*
* @returns List of GraphQL types for each Shared Slice variation.
*/
export const buildSharedSliceVariationTypes = (
path: string[],
variations: prismicT.SharedSliceModel["variations"],
): RTE.ReaderTaskEither<
Dependencies,
Error,
gatsby.GatsbyGraphQLObjectType[]
> =>
pipe(
RTE.right(variations),
RTE.map(
ReadonlyA.map((variation) =>
buildSharedSliceVariationType(path, variation),
),
),
RTE.chain(RTE.sequenceArray),
RTE.map((types) => types as Mutable<typeof types>),
);