add path validation in PagesSchema

This commit is contained in:
Roman Pominov committed 2022-10-17 08:46:19 +04:00
1 parent a27bbcaf04
commit c2e8ff642d
4 files changed
+41 -12

No files matched your search

@@ -102,7 +102,7 @@ const Pages = ({
actions={
<>
{onNewPage && (
<IconButton size="2" onClick={onNewPage} aria-label="Close">
<IconButton size="2" onClick={onNewPage} aria-label="New Page">
<NewPageIcon />
</IconButton>
)}
@@ -23,7 +23,7 @@ const Group = styled(Flex, {
defaultVariants: { direction: "column" },
});
export type PutPageData =
export type CreatePageData =
| { ok: true; page: Page }
| { errors: string | ZodError["formErrors"] };
@@ -67,7 +67,7 @@ export const NewPageSettings = ({
const nameFieldId = useId();
const pathFieldId = useId();
const fetcher = useFetcher<PutPageData>();
const fetcher = useFetcher<CreatePageData>();
const [fieldErrors, setFieldErrors] = useState<
ZodError["formErrors"]["fieldErrors"]
@@ -107,7 +107,7 @@ export const NewPageSettings = ({
actions={
<>
{onClose && (
<IconButton size="2" onClick={onClose} aria-label="Close">
<IconButton size="2" onClick={onClose} aria-label="Cancel">
<ChevronDoubleLeftIcon />
</IconButton>
)}
@@ -3,7 +3,7 @@ import { db } from "@webstudio-is/project/index.server";
import { type Pages, utils } from "@webstudio-is/project";
import { zfd } from "zod-form-data";
import { z } from "zod";
import { PutPageData } from "~/designer/features/sidebar-left/panels/pages/settings";
import { CreatePageData } from "~/designer/features/sidebar-left/panels/pages/settings";
import { sentryException } from "~/shared/sentry";
const nonEmptyString = z
@@ -33,7 +33,7 @@ const CreatePageInput = zfd.formData({
const handlePUT = async (
projectId: string,
request: Request
): Promise<PutPageData> => {
): Promise<CreatePageData> => {
const result = CreatePageInput.safeParse(await request.formData());
if (result.success === false) {
return { errors: result.error.formErrors };
@@ -72,7 +72,7 @@ export const action: ActionFunction = async ({ request, params }) => {
}
if (request.method.toLowerCase() === "put") {
return handlePUT(params.projectId, request);
await handlePUT(params.projectId, request);
}
throw new Error(`Method ${request.method} is not supported`);
+34 -5
View File
@@ -9,21 +9,50 @@ export type Project = Omit<BaseProject, "assets"> & {
assets?: Array<Asset>;
};
export const PageSchema = z.object({
const commonPageFields = {
id: z.string(),
name: z.string(),
path: z.string(),
name: z.string().refine((val) => val !== "", "Can't be empty"),
title: z.string(),
meta: z.record(z.string(), z.string()),
treeId: z.string(),
} as const;
const HomePageSchema = z.object({
...commonPageFields,
path: z
.string()
.refine((path) => path === "", "Home page path must be empty"),
});
const PageSchema = z.object({
...commonPageFields,
path: z
.string()
.refine((path) => path !== "" && path !== "/", "Can't be empty")
.refine((path) => path.startsWith("/"), "Must start with a /")
.refine((path) => path.endsWith("/") === false, "Can't end with a /")
.refine(
(path) => path.includes("//") === false,
"Can't contain repeating /"
)
.refine(
(path) => /^[-_a-z0-9\\/]*$/.test(path),
"Only a-z, 0-9, -, _ and / are allowed"
),
});
export type Page = z.infer<typeof PageSchema>;
export const PagesSchema: z.ZodType<{ homePage: Page; pages: Array<Page> }> =
z.object({
homePage: PageSchema,
pages: z.array(PageSchema),
homePage: HomePageSchema,
pages: z
.array(PageSchema)
.refine(
(array) =>
new Set(array.map((page) => page.path)).size === array.length,
"All paths must be unique"
),
});
export type Pages = z.infer<typeof PagesSchema>;