Skip to content

Commit

Permalink
seperate validator logic
Browse files Browse the repository at this point in the history
  • Loading branch information
tstikvoort committed Jul 12, 2024
1 parent 08fa754 commit 3fc5681
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 29 deletions.
1 change: 1 addition & 0 deletions examples/studio-i18n/page-tree-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export const pageTreeConfig: PageTreeConfig = {
titleFieldName: 'title',
documentInternationalization: {
supportedLanguages: ['nl', 'en', 'fr'],
documentLanguageShouldMatchParent: true,
}
};
4 changes: 2 additions & 2 deletions src/schema/definePageType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { defineField, defineType, DocumentDefinition, SlugOptions } from 'sanity
import { PageTreeField } from '../components/PageTreeField';
import { SlugField } from '../components/SlugField';
import { PageTreeConfig } from '../types';
import { allowedParentValidator } from '../validators/parent-validator';
import { parentValidator } from '../validators/parent-validator';
import { slugValidator } from '../validators/slug-validator';

type Options = {
Expand Down Expand Up @@ -67,7 +67,7 @@ const basePageFields = (config: PageTreeConfig, options: Options, ownType: Docum
title: 'Parent page',
type: 'reference',
to: getPossibleParentsFromConfig(config, ownType).map(type => ({ type })),
validation: Rule => Rule.required().custom(allowedParentValidator(config, ownType.name)),
validation: Rule => Rule.required().custom(parentValidator(config, ownType.name)),
group: options.fieldsGroupName,
components: {
field: props => PageTreeField({ ...props, config, mode: 'select-parent' }),
Expand Down
66 changes: 39 additions & 27 deletions src/validators/parent-validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,59 @@ import { Reference, ValidationContext } from 'sanity';

import { getLanguageFieldName } from '../helpers/config';
import { getRawPageMetadataQuery } from '../queries';
import { PageTreeConfig, RawPageMetadata, SanityRef } from '../types';
import { PageTreeConfig, RawPageMetadata } from '../types';

/**
* Validates that the slug is unique within the parent page and therefore that entire the path is unique.
*/
export const allowedParentValidator =
export const parentValidator =
(config: PageTreeConfig, ownType: string) =>
async (selectedParentRef: Reference | undefined, context: ValidationContext) => {
const allowedParents = config.allowedParents?.[ownType];

const parentRef = context.document?.parent as SanityRef | undefined;
if (!parentRef) {
return true;
}

const parentId = parentRef._ref;
const client = context.getClient({ apiVersion: config.apiVersion });

if (parentId === undefined) {
if (!selectedParentRef) {
return true;
}

const client = context.getClient({ apiVersion: config.apiVersion });
const selectedParent = (await client.fetch<RawPageMetadata[]>(getRawPageMetadataQuery(parentId, config)))?.[0];
const parentId = selectedParentRef._ref;
const selectedParent = (await client.fetch<RawPageMetadata[]>(getRawPageMetadataQuery(parentId, config)))[0];

if (!selectedParent._type) {
return 'Unable to check the type of the selected parent.';
const allowedParentValidation = allowedParentValidator(selectedParent, config, ownType);
if (allowedParentValidation !== true) {
return allowedParentValidation;
}

if (allowedParents && !allowedParents.includes(selectedParent._type)) {
return `The parent of type "${selectedParent._type}" is not allowed for this type of document.`;
}
return parentLanguageValidator(selectedParent, config, context);
};

if (config.documentInternationalization?.documentLanguageShouldMatchParent) {
const languageFieldName = getLanguageFieldName(config);
const language = context.document?.[languageFieldName];
const parentLanguage = selectedParent?.[languageFieldName];
const allowedParentValidator = (selectedParent: RawPageMetadata, config: PageTreeConfig, ownType: string) => {
const allowedParents = config.allowedParents?.[ownType];

if (language !== parentLanguage) {
return 'The language of the parent must match the language of the document.';
}
if (allowedParents === undefined) {
return true;
}

if (!allowedParents.includes(selectedParent._type)) {
return `The parent of type "${selectedParent._type}" is not allowed for this type of document.`;
}

return true;
};

const parentLanguageValidator = (
selectedParent: RawPageMetadata,
config: PageTreeConfig,
context: ValidationContext,
) => {
if (config.documentInternationalization?.documentLanguageShouldMatchParent) {
const languageFieldName = getLanguageFieldName(config);
const language = context.document?.[languageFieldName];
const parentLanguage = selectedParent?.[languageFieldName];

if (language !== parentLanguage) {
return 'The language of the parent must match the language of the document.';
}
}

return true;
};
return true;
};

0 comments on commit 3fc5681

Please sign in to comment.