@prismicio/mock
Version:
Generate mock Prismic documents, fields, Slices, and models for development and testing environments
161 lines (135 loc) • 4.14 kB
text/typescript
import * as prismic from "@prismicio/client"
import type { ModelValue, ModelValueMap, Seed } from "../types"
import type {
MockBooleanValueConfig,
MockColorValueConfig,
MockContentRelationshipValueConfig,
MockDateValueConfig,
MockEmbedValueConfig,
MockGeoPointValueConfig,
MockGroupValueConfig,
MockImageValueConfig,
MockIntegrationFieldValueConfig,
MockKeyTextValueConfig,
MockLinkToMediaValueConfig,
MockLinkValueConfig,
MockNumberValueConfig,
MockRichTextValueConfig,
MockSelectValueConfig,
MockSliceZoneValueConfig,
MockTimestampValueConfig,
MockTitleValueConfig,
MockUIDValueConfig,
} from "../value"
import { createFaker, type Faker } from "./createFaker"
import { valueForModel } from "./valueForModel"
const getValueConfigType = <Model extends prismic.CustomTypeModelField>(
model: Model,
): keyof ValueForModelMapConfigs => {
switch (model.type) {
case prismic.CustomTypeModelFieldType.Boolean:
return "boolean"
case prismic.CustomTypeModelFieldType.Color:
return "color"
case prismic.CustomTypeModelFieldType.Date:
return "date"
case prismic.CustomTypeModelFieldType.Embed:
return "embed"
case prismic.CustomTypeModelFieldType.GeoPoint:
return "geoPoint"
case prismic.CustomTypeModelFieldType.Group:
return "group"
case prismic.CustomTypeModelFieldType.Image:
return "image"
case prismic.CustomTypeModelFieldType.Link: {
switch (model.config?.select) {
case prismic.CustomTypeModelLinkSelectType.Document:
return "contentRelationship"
case prismic.CustomTypeModelLinkSelectType.Media:
return "linkToMedia"
default:
return "link"
}
}
case prismic.CustomTypeModelFieldType.Number:
return "number"
case prismic.CustomTypeModelFieldType.Select:
return "select"
case prismic.CustomTypeModelFieldType.StructuredText: {
if (
model.config &&
"single" in model.config &&
model.config.single &&
model.config.single.split(",").every((element) => /heading{1,6}/.test(element.trim()))
) {
return "title"
} else {
return "richText"
}
}
case prismic.CustomTypeModelFieldType.Text:
return "keyText"
case prismic.CustomTypeModelFieldType.Timestamp:
return "timestamp"
case prismic.CustomTypeModelFieldType.UID:
return "uid"
case prismic.CustomTypeModelFieldType.Integration:
return "integration"
case prismic.CustomTypeModelFieldType.Slices:
return "sliceZone"
default: {
throw new Error(`The "${model.type}" field type is not supported in /mock.`)
}
}
}
export type ValueForModelMapConfigs = {
boolean?: MockBooleanValueConfig
color?: MockColorValueConfig
contentRelationship?: MockContentRelationshipValueConfig
date?: MockDateValueConfig
embed?: MockEmbedValueConfig
geoPoint?: MockGeoPointValueConfig
group?: MockGroupValueConfig
image?: MockImageValueConfig
integration?: MockIntegrationFieldValueConfig
keyText?: MockKeyTextValueConfig
link?: MockLinkValueConfig
linkToMedia?: MockLinkToMediaValueConfig
number?: MockNumberValueConfig
richText?: MockRichTextValueConfig
select?: MockSelectValueConfig
sliceZone?: MockSliceZoneValueConfig
timestamp?: MockTimestampValueConfig
title?: MockTitleValueConfig
uid?: MockUIDValueConfig
}
type ValueForModelMapConfig<ModelMap extends Record<string, prismic.CustomTypeModelField>> = {
map: ModelMap
configs?: ValueForModelMapConfigs
} & (
| {
seed: Seed
faker?: never
}
| {
faker: Faker
seed?: never
}
)
export const valueForModelMap = <ModelMap extends Record<string, prismic.CustomTypeModelField>>(
config: ValueForModelMapConfig<ModelMap>,
): ModelValueMap<ModelMap> => {
const faker = config.faker || createFaker(config.seed)
const result = {} as ModelValueMap<ModelMap>
for (const fieldId in config.map) {
const fieldModel = config.map[fieldId]
const fieldConfigType = getValueConfigType(fieldModel)
const fieldConfig = config.configs?.[fieldConfigType]
result[fieldId] = valueForModel({
faker,
model: fieldModel as prismic.CustomTypeModelField,
config: fieldConfig,
}) as ModelValue<typeof fieldModel>
}
return result
}