diff --git a/src/content.ts b/src/content.ts index 4430893..a31ab25 100644 --- a/src/content.ts +++ b/src/content.ts @@ -44,15 +44,16 @@ export function stringifyContent(collections: CollectionModel[], opts: GenerateO function stringifyField(field: CollectionField, collectionName: string) { let schema: string; - // if (collectionName === "relations") console.log(`${collectionName}:`, field); switch (field.type) { case "bool": schema = "z.boolean()"; break; case "date": - // TODO: implement min and max - schema = "z.string().pipe(z.coerce.date())"; + const minConstraintDate = field.min ? `.min(new Date("${field.min}"))` : ""; + const maxConstraintDate = field.max ? `.max(new Date("${field.max}"))` : ""; + + schema = `z.string().pipe(z.coerce.date()${minConstraintDate}${maxConstraintDate})`; break; case "editor": @@ -61,11 +62,14 @@ export function stringifyContent(collections: CollectionModel[], opts: GenerateO break; case "email": - // TODO: implement exceptDomains and onlyDomains - schema = "z.string().email()"; + const onlyDomainsConstraint = createEmailDomainConstraint(field.onlyDomains, true); + const exceptDomainsConstraint = createEmailDomainConstraint(field.exceptDomains, false); + + schema = `z.string().email()${onlyDomainsConstraint}${exceptDomainsConstraint}`; break; case "file": + // if (collectionName === "tests") console.log(`${collectionName}:`, field); const maxSelectFile = field.maxSelect; // TODO: implement maxSize, mimeTypes, protected, thumbs schema = `z.string()${maxSelectFile === 1 ? "" : `.array()${maxSelectFile ? `.max(${maxSelectFile})` : ""}`}`; @@ -126,6 +130,15 @@ export function stringifyContent(collections: CollectionModel[], opts: GenerateO return `${field.name}: ${schema}${(field as any).required ? "" : ".optional()"}`; } + /* Helpers */ + + const createEmailDomainConstraint = (domains: string[], isWhitelist: boolean) => { + if (!domains?.length) return ""; + const domainsList = domains.map((domain) => `"${domain}"`).join(", "); + const messageType = isWhitelist ? "isn't one of the allowed ones" : "is one of the disallowed ones"; + return `.refine((email) => { const domain = email.split("@")[1]; return domain && ${isWhitelist ? "" : "!"}[${domainsList}].includes(domain); }, { message: "Invalid email, email domain ${messageType}" })`; + }; + return { collectionNames: `[\n\t${collections.map(({ name }) => `"${name}"`).join(",\n\t")},\n]`, enums: getCollectionSelectFields().map(stringifyEnum).join("\n\n"),