gatsby-source-prismic
Version:
Gatsby source plugin for building websites using Prismic as a data source
348 lines (343 loc) • 13.7 kB
JavaScript
import { CustomTypeModelFieldType, isFilled, CustomTypeModelSliceType, CustomTypeModelLinkSelectType } from "@prismicio/client";
import { buildImageObjectType } from "./buildImageObjectType.js";
import { defaultTransformFieldName } from "./defaultTransformFieldName.js";
import { fieldModelsRecordToGraphQLType } from "./fieldModelsRecordToGraphQLType.js";
import { fmtLog } from "./fmtLog.js";
import { pascalCase } from "./pascalCase.js";
const fieldModelToGraphQLConfig = (args) => {
var _a, _b, _c, _d, _e, _f;
switch (args.model.type) {
case CustomTypeModelFieldType.Boolean: {
return {
type: "Boolean",
description: "A Boolean field."
};
}
case CustomTypeModelFieldType.Color: {
return {
type: "String",
description: "A Color field."
};
}
case CustomTypeModelFieldType.Date: {
return {
type: "Date",
description: "A Date field.",
extensions: { dateformat: {} }
};
}
case CustomTypeModelFieldType.Embed: {
return {
type: pascalCase("Prismic", args.pluginOptions.typePrefix, "EmbedField"),
description: "An Embed field.",
extensions: { link: {} }
};
}
case CustomTypeModelFieldType.GeoPoint: {
return {
type: "PrismicGeoPointField",
description: "A GeoPoint field.",
resolve: (source, _args, _context, info) => {
const field = source[info.fieldName];
if (isFilled.geoPoint(field)) {
return field;
} else {
return null;
}
}
};
}
case CustomTypeModelFieldType.Group: {
const type = fieldModelsRecordToGraphQLType({
...args,
models: ((_a = args.model.config) == null ? void 0 : _a.fields) || {}
});
type.config.name = pascalCase("Prismic", args.pluginOptions.typePrefix, args.path.join(" "), "Item");
type.config.description = "An item for a Group field.";
args.gatsbyNodeArgs.actions.createTypes(type);
return {
type: `[${type.config.name}!]!`,
description: "A Group field."
};
}
case CustomTypeModelFieldType.Image: {
if (((_b = args.model.config) == null ? void 0 : _b.thumbnails) && args.model.config.thumbnails.length > 0) {
const type = buildImageObjectType({
schema: args.gatsbyNodeArgs.schema,
cache: args.gatsbyNodeArgs.cache,
pluginOptions: args.pluginOptions
});
type.config.name = pascalCase("Prismic", args.pluginOptions.typePrefix, args.path.join(" "), "ImageField");
const thumbnailsType = args.gatsbyNodeArgs.schema.buildObjectType({
name: pascalCase("Prismic", args.pluginOptions.typePrefix, args.path.join(" "), "ImageFieldThumbnails"),
description: "Thumbnails for an image field.",
fields: {}
});
for (const thumbnailModel of args.model.config.thumbnails) {
if (thumbnailsType.config.fields) {
const transformedThumbnailName = args.pluginOptions.transformFieldName ? args.pluginOptions.transformFieldName(thumbnailModel.name) : defaultTransformFieldName(thumbnailModel.name);
thumbnailsType.config.fields[transformedThumbnailName] = {
type: pascalCase("Prismic", args.pluginOptions.typePrefix, "ImageField")
};
}
}
if (type.config.fields) {
type.config.fields.thumbnails = {
type: `${thumbnailsType.config.name}!`,
description: "Thumbnails for the image field.",
resolve: (source) => {
return source;
}
};
}
args.gatsbyNodeArgs.actions.createTypes(thumbnailsType);
args.gatsbyNodeArgs.actions.createTypes(type);
return {
type: type.config.name,
description: "An Image field with thumbnails."
};
} else {
return {
type: pascalCase("Prismic", args.pluginOptions.typePrefix, "ImageField"),
description: "An Image field."
};
}
}
case CustomTypeModelFieldType.Link: {
const type = pascalCase("Prismic", args.pluginOptions.typePrefix, "LinkField");
switch ((_c = args.model.config) == null ? void 0 : _c.select) {
case CustomTypeModelLinkSelectType.Document: {
return {
type,
description: "A Content Relationship field.",
resolve: (source, _args, _context, info) => {
const field = source[info.fieldName];
if (isFilled.contentRelationship(field)) {
return field;
} else {
return null;
}
}
};
}
case CustomTypeModelLinkSelectType.Media: {
return {
type,
description: `A Link to Media field.
To download linked files locally and populate the \`localFile\` field, add the following path to \`gatsby-source-prismic\`'s \`shouldDownloadFiles\` option:
\`"${args.path.join(".")}": true,\``,
resolve: (source, _args, _context, info) => {
const field = source[info.fieldName];
if (isFilled.linkToMedia(field)) {
return field;
} else {
return null;
}
}
};
}
case null:
default: {
return {
type,
description: `A Link field.
To download linked files locally and populate the \`localFile\` field, add the following path to \`gatsby-source-prismic\`'s \`shouldDownloadFiles\` option:
\`"${args.path.join(".")}": true,\``,
resolve: (source, _args, _context, info) => {
const field = source[info.fieldName];
if (isFilled.link(field)) {
return field;
} else {
return null;
}
}
};
}
}
}
case CustomTypeModelFieldType.Number: {
return {
type: "Float",
description: "A Number field."
};
}
case CustomTypeModelFieldType.Select: {
if (((_d = args.model.config) == null ? void 0 : _d.default_value) !== void 0) {
return {
type: "String",
description: `A Select field with a default value. **Default value**: ${args.model.config.default_value}`
};
} else {
return {
type: "String",
description: "A Select field without a default value."
};
}
}
case CustomTypeModelFieldType.Slices: {
let choiceTypeNames = [];
if ((_e = args.model.config) == null ? void 0 : _e.choices) {
for (const sliceType in args.model.config.choices) {
const model = args.model.config.choices[sliceType];
switch (model.type) {
case CustomTypeModelSliceType.SharedSlice: {
const sharedSliceModel = args.sharedSliceModels.find((model2) => {
return model2.id === sliceType;
});
if (sharedSliceModel) {
for (const variation of sharedSliceModel.variations) {
choiceTypeNames = [
...choiceTypeNames,
pascalCase("Prismic", args.pluginOptions.typePrefix, sliceType, "Slice", variation.id)
];
}
}
break;
}
case CustomTypeModelSliceType.Slice: {
const type = args.gatsbyNodeArgs.schema.buildObjectType({
name: pascalCase("Prismic", args.pluginOptions.typePrefix, args.path.join(" "), sliceType),
fields: {
id: {
type: "ID!",
resolve: (source) => {
return source.id || args.gatsbyNodeArgs.createNodeId(args.gatsbyNodeArgs.createContentDigest(source));
}
},
slice_type: {
type: "String!"
},
slice_label: {
type: "String"
}
},
interfaces: ["PrismicSlice"]
});
if (model["non-repeat"] && Object.keys(model["non-repeat"]).length > 0) {
const primaryType = fieldModelsRecordToGraphQLType({
...args,
path: [...args.path, sliceType, "primary"],
models: model["non-repeat"]
});
args.gatsbyNodeArgs.actions.createTypes(primaryType);
if (type.config.fields) {
type.config.fields.primary = {
type: `${primaryType.config.name}!`
};
}
}
if (model.repeat && Object.keys(model.repeat).length > 0) {
const itemType = fieldModelsRecordToGraphQLType({
...args,
path: [...args.path, sliceType, "items"],
models: model.repeat
});
itemType.config.name = pascalCase("Prismic", args.pluginOptions.typePrefix, args.path.join(" "), sliceType, "item");
args.gatsbyNodeArgs.actions.createTypes(itemType);
if (type.config.fields) {
type.config.fields.items = {
type: `[${itemType.config.name}!]!`
};
}
}
args.gatsbyNodeArgs.actions.createTypes(type);
choiceTypeNames = [...choiceTypeNames, type.config.name];
break;
}
default: {
throw new Error(fmtLog(args.pluginOptions.repositoryName, `Legacy Slices are not supported, but were found at this field: ${args.path.join(".")}`));
}
}
}
}
if (choiceTypeNames.length > 0) {
const type = args.gatsbyNodeArgs.schema.buildUnionType({
name: pascalCase("Prismic", args.pluginOptions.typePrefix, args.path.join(" ")),
types: choiceTypeNames,
resolveType: (source) => {
if ("variation" in source) {
return pascalCase("Prismic", args.pluginOptions.typePrefix, source.slice_type, "Slice", source.variation);
} else {
return pascalCase("Prismic", args.pluginOptions.typePrefix, args.path.join(" "), source.slice_type);
}
}
});
args.gatsbyNodeArgs.actions.createTypes(type);
return {
type: `[${type.config.name}!]!`
};
} else {
return void 0;
}
}
case CustomTypeModelFieldType.StructuredText: {
const type = `${pascalCase("Prismic", args.pluginOptions.typePrefix, "RichTextField")}!`;
if (args.model.config && "single" in args.model.config && args.model.config.single && args.model.config.single.split(",").every((blockType) => /^heading/.test(blockType))) {
return {
type,
description: "A Title field."
};
} else {
return {
type,
description: "A Rich Text field."
};
}
}
case CustomTypeModelFieldType.Text: {
return {
type: "String",
description: "A Key Text field.",
// TODO: Restore this resolver.
resolve: (source, _args, _context, info) => {
const field = source[info.fieldName];
if (isFilled.keyText(field)) {
return field;
} else {
return null;
}
}
};
}
case CustomTypeModelFieldType.Timestamp: {
return {
type: "Date",
description: "A Timestamp field.",
extensions: { dateformat: {} }
};
}
case CustomTypeModelFieldType.Integration: {
if (!((_f = args.model.config) == null ? void 0 : _f.catalog)) {
throw new Error(fmtLog(args.pluginOptions.repositoryName, `Integration fields must have a catalog configured, but none was found for this field: ${args.path.join(".")}`));
}
const type = args.gatsbyNodeArgs.schema.buildObjectType({
name: pascalCase("Prismic", args.pluginOptions.typePrefix, args.model.config.catalog, "IntegrationItem"),
description: `An Integration Fields field connected to the \`${args.model.config.catalog}\` catalog.`,
fields: {
// At least one field must be defined to supress a graphql-compose error.
id: "ID!"
},
interfaces: ["Node"],
extensions: { infer: true }
});
args.gatsbyNodeArgs.actions.createTypes(type);
return {
type: type.config.name,
description: `An Integration Fields field connected to the \`${args.model.config.catalog}\` catalog.`,
extensions: { link: {} }
};
}
default: {
const dotPath = args.path.join(".");
args.gatsbyNodeArgs.reporter.info(fmtLog(args.pluginOptions.repositoryName, `An unknown field type "${args.model.type}" was found at ${dotPath}. A generic JSON type will be used. You can manually override the type using Gatsby's createSchemaCustomization API in your site's gatsby-node.js.`));
return {
type: "JSON",
description: `This field's type is unknown ("${args.model.type}"). A generic \`JSON\` type is used. You can manually override the type using Gatsby's [\`createSchemaCustomization\`](https://www.gatsbyjs.com/docs/reference/graphql-data-layer/schema-customization/) Node API in your site's \`gatsby-node.js\`.`
};
}
}
};
export {
fieldModelToGraphQLConfig
};
//# sourceMappingURL=fieldModelToGraphQLConfig.js.map