Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to provide custom slug validation #36

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions src/schema/definePageType.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { compact, get } from 'lodash';
import { defineField, defineType, DocumentDefinition, SlugOptions } from 'sanity';
import { defineField, defineType, DocumentDefinition } from 'sanity';

import { PageTreeField } from '../components/PageTreeField';
import { SlugField } from '../components/SlugField';
import { PageTreeConfig } from '../types';
import { PageTreeConfig, GlobalOptions } from '../types';
import { slugValidator } from '../validators/slug-validator';

import { allowedParentValidator } from '../validators/parent-validator';

type Options = {
type Options = GlobalOptions & {
isRoot?: boolean;
fieldsGroupName?: string;
slugSource?: SlugOptions['source'];
};

function getPossibleParentsFromConfig(config: PageTreeConfig, ownType: DocumentDefinition): string[] {
Expand All @@ -26,6 +24,7 @@ export const definePageType = (
config: PageTreeConfig,
options: Options = { isRoot: false },
) => {
options = {...config.globalOptions, ...options};
const slugSourceFieldName = getSlugSourceField(config, options);

let slugSourceField;
Expand Down Expand Up @@ -56,7 +55,10 @@ const basePageFields = (config: PageTreeConfig, options: Options, ownType: Docum
components: {
input: props => SlugField({ ...props, config }),
},
validation: Rule => Rule.required().custom(slugValidator(config)),
validation: Rule => [
Rule.required().custom(slugValidator(config)),
...toArray(options.slugValidationRules?.(Rule))
],
group: options.fieldsGroupName,
}),
]
Expand All @@ -79,3 +81,4 @@ const basePageFields = (config: PageTreeConfig, options: Options, ownType: Docum
];

const getSlugSourceField = (config: PageTreeConfig, options: Options) => config.titleFieldName ?? options.slugSource;
const toArray = <T>(t: undefined | T | T[]) => t === undefined ? [] : Array.isArray(t) ? t : [t];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bit nitpicky, but could you move this to an array-utils.ts in the utils folder?

27 changes: 18 additions & 9 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { DocumentListBuilder } from 'sanity/structure';
import { SlugOptions, SlugRule, SlugValue, ValidationBuilder } from 'sanity';

export type SanityRef = {
_ref: string;
Expand Down Expand Up @@ -35,29 +36,37 @@ export type PageTreeItem = RawPageMetadataWithPublishedState & {
path: string;
};

export type GlobalOptions = {
fieldsGroupName?: string;
slugSource?: SlugOptions['source'];
slugValidationRules?: ValidationBuilder<SlugRule, SlugValue>
}

Comment on lines +39 to +44
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we expose the Options outside of the definePageType function / file, a more specific name would be better, like PageTypeOptions.

By defining in the page tree config, global is implied.

/**
* @public
*/
export type PageTreeConfig = {
/* Api version that is used throughout your project */
/** Api version that is used throughout your project */
apiVersion: string;
/* Root page schema type name, e.g. "homePage" */
/** Root page schema type name, e.g. "homePage" */
rootSchemaType: string;
/* All your page schema type names, e.g. ["homePage", "contentPage"] */
/** All your page schema type names, e.g. ["homePage", "contentPage"] */
pageSchemaTypes: string[];
/* Field name of your page documents */
/** @deprecated Use globalOptions.slugSource instead. Field name of your page documents */
titleFieldName?: string;
/* Optionally specify which document types can be the parent of a document type */
/** Optionally specify which document types can be the parent of a document type */
allowedParents?: Record<string, string[]>;
/* Used for creating page link on the editor page */
/** Used for creating page link on the editor page */
baseUrl?: string;
/* This plugin supports the document-internationalization plugin. To use it properly, provide the supported languages. */
/** This plugin supports the document-internationalization plugin. To use it properly, provide the supported languages. */
documentInternationalization?: {
/* Array of supported language code strings, e.g. ["en", "nl"]. These will be used in root pages and when creating a new child page it will set the language field based on the parent page. */
/** Array of supported language code strings, e.g. ["en", "nl"]. These will be used in root pages and when creating a new child page it will set the language field based on the parent page. */
supportedLanguages: string[];
/* Optional field name of the language field, defaults to "language" */
/** Optional field name of the language field, defaults to "language" */
languageFieldName?: string;
};
/** Define options that apply to all pages. Can be overridden by options supplied using definePageType */
globalOptions?: GlobalOptions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same goes for this propertyName then.

};

/**
Expand Down