gatsby-source-prismic
Version:
Gatsby source plugin for building websites using Prismic as a data source
185 lines (166 loc) • 4.18 kB
text/typescript
import * as prismicT from "@prismicio/types";
import {
PrismicSpecialType,
TransformFieldNameFn,
TypePath,
TypePathKind,
} from "../types";
const fieldToTypePaths = <
Model extends prismicT.CustomTypeModelField | prismicT.CustomTypeModelSlice,
>(
path: string[],
model: Model,
transformFieldName: TransformFieldNameFn,
): TypePath[] => {
switch (model.type) {
case prismicT.CustomTypeModelFieldType.UID: {
return [];
}
case prismicT.CustomTypeModelFieldType.Group: {
const fields = Object.entries(model.config.fields).flatMap(
([fieldId, fieldModel]) =>
fieldToTypePaths(
[...path, transformFieldName(fieldId)],
fieldModel,
transformFieldName,
),
);
return [{ kind: TypePathKind.Field, type: model.type, path }, ...fields];
}
case prismicT.CustomTypeModelFieldType.Slices: {
const choices = (
(model.config.choices && Object.entries(model.config.choices)) ||
[]
)
.filter(
(entry): entry is [string, prismicT.CustomTypeModelSlice] =>
entry[1].type === prismicT.CustomTypeModelSliceType.Slice,
)
.flatMap(([choiceId, choiceModel]) =>
fieldToTypePaths(
[...path, choiceId],
choiceModel,
transformFieldName,
),
);
return [{ kind: TypePathKind.Field, type: model.type, path }, ...choices];
}
case prismicT.CustomTypeModelSliceType.Slice: {
const primary = Object.entries(model["non-repeat"] || {}).flatMap(
([fieldId, fieldModel]) =>
fieldToTypePaths(
[...path, "primary", transformFieldName(fieldId)],
fieldModel,
transformFieldName,
),
);
const items = Object.entries(model.repeat || {}).flatMap(
([fieldId, fieldModel]) =>
fieldToTypePaths(
[...path, "items", transformFieldName(fieldId)],
fieldModel,
transformFieldName,
),
);
return [
{ kind: TypePathKind.Field, type: model.type, path },
...primary,
...items,
];
}
default: {
return [
{
kind: TypePathKind.Field,
path,
type: model.type,
},
];
}
}
};
export const customTypeModelToTypePaths = <
Model extends prismicT.CustomTypeModel,
>(
customTypeModel: Model,
transformFieldName: TransformFieldNameFn,
): TypePath[] => {
const definition = customTypeModel.json;
const fieldModels = Object.assign({}, ...Object.values(definition)) as Record<
string,
prismicT.CustomTypeModelField
>;
const hasDataFields =
Object.values(fieldModels).filter(
(fieldModel) => fieldModel.type !== prismicT.CustomTypeModelFieldType.UID,
).length > 0;
const documentTypePath = {
kind: TypePathKind.CustomType,
type: PrismicSpecialType.Document,
path: [customTypeModel.id],
};
if (hasDataFields) {
const data = Object.entries(fieldModels).flatMap(([fieldId, fieldModel]) =>
fieldToTypePaths(
[customTypeModel.id, "data", transformFieldName(fieldId)],
fieldModel,
transformFieldName,
),
);
return [
documentTypePath,
{
kind: TypePathKind.Field,
type: PrismicSpecialType.DocumentData,
path: [customTypeModel.id, "data"],
},
...data,
];
} else {
return [documentTypePath];
}
};
export const sharedSliceModelToTypePaths = <
Model extends prismicT.SharedSliceModel,
>(
sharedSliceModel: Model,
transformFieldName: TransformFieldNameFn,
): TypePath[] => {
return sharedSliceModel.variations.flatMap((variation) => {
const primary = Object.entries(variation.primary || {}).flatMap(
([fieldId, fieldModel]) =>
fieldToTypePaths(
[
sharedSliceModel.id,
variation.id,
"primary",
transformFieldName(fieldId),
],
fieldModel,
transformFieldName,
),
);
const items = Object.entries(variation.items || {}).flatMap(
([fieldId, fieldModel]) =>
fieldToTypePaths(
[
sharedSliceModel.id,
variation.id,
"items",
transformFieldName(fieldId),
],
fieldModel,
transformFieldName,
),
);
return [
{
kind: TypePathKind.SharedSliceVariation,
type: PrismicSpecialType.SharedSliceVariation,
path: [sharedSliceModel.id, variation.id],
},
...primary,
...items,
];
});
};