@prismicio/mock
Version:
Generate mock Prismic documents, fields, Slices, and models for development and testing environments
113 lines (100 loc) • 3.33 kB
text/typescript
import * as prismic from "@prismicio/client";
import { sentenceCase } from "../lib/changeCase";
import { createFaker } from "../lib/createFaker";
import { MockValueStateConfig, MockValueConfig } from "../types";
import * as modelGen from "../model";
import { contentRelationship } from "./contentRelationship";
import { linkToMedia } from "./linkToMedia";
export type MockLinkValueConfig<
LinkType extends
(typeof prismic.LinkType)[keyof typeof prismic.LinkType] = (typeof prismic.LinkType)[keyof typeof prismic.LinkType],
Model extends
prismic.CustomTypeModelLinkField = prismic.CustomTypeModelLinkField,
State extends prismic.FieldState = prismic.FieldState,
> = {
type?: LinkType;
withTargetBlank?: NonNullable<
Model["config"]
>["allowTargetBlank"] extends undefined
? false
: boolean;
withText?: NonNullable<Model["config"]>["allowText"] extends undefined
? false
: boolean;
/**
* A list of potential documents to which the field can be linked.
*/
linkableDocuments?: LinkType extends typeof prismic.LinkType.Document
? prismic.PrismicDocument[]
: never;
} & MockValueConfig<Model> &
MockValueStateConfig<State>;
type MockLinkValue<
LinkType extends
(typeof prismic.LinkType)[keyof typeof prismic.LinkType] = (typeof prismic.LinkType)[keyof typeof prismic.LinkType],
State extends prismic.FieldState = "filled",
> = State extends "empty"
? prismic.EmptyLinkField<LinkType>
: LinkType extends typeof prismic.LinkType.Web
? prismic.FilledLinkToWebField
: LinkType extends typeof prismic.LinkType.Media
? prismic.FilledLinkToMediaField
: LinkType extends typeof prismic.LinkType.Document
? prismic.FilledContentRelationshipField
: never;
export const link = <
LinkType extends
(typeof prismic.LinkType)[keyof typeof prismic.LinkType] = (typeof prismic.LinkType)[keyof typeof prismic.LinkType],
Model extends
prismic.CustomTypeModelLinkField = prismic.CustomTypeModelLinkField,
State extends prismic.FieldState = "filled",
>(
config: MockLinkValueConfig<LinkType, Model, State>,
): MockLinkValue<LinkType, State> => {
const faker = config.faker || createFaker(config.seed);
const type =
config.type ||
faker.randomElement([
prismic.LinkType.Web,
prismic.LinkType.Document,
prismic.LinkType.Media,
]);
if (config.state === "empty") {
return {
link_type: type,
} as MockLinkValue<LinkType, State>;
} else {
switch (type) {
case prismic.LinkType.Document: {
return contentRelationship({
faker,
state: config.state,
linkableDocuments: config.linkableDocuments,
}) as unknown as MockLinkValue<LinkType, State>;
}
case prismic.LinkType.Media: {
return linkToMedia({
faker,
state: config.state,
withText: config.withText,
}) as MockLinkValue<LinkType, State>;
}
case prismic.LinkType.Web:
default: {
const model = config.model || modelGen.link({ faker });
return {
link_type: prismic.LinkType.Web,
url: faker.url(),
target:
config.withTargetBlank ??
(model.config?.allowTargetBlank && faker.boolean())
? "_blank"
: undefined,
...(config.withText ?? (model.config?.allowText && faker.boolean())
? { text: sentenceCase(faker.words(2)) }
: {}),
} as MockLinkValue<LinkType, State>;
}
}
}
};