From 7807ade3e80de1e50b367d43c260fafb85132287 Mon Sep 17 00:00:00 2001 From: Francisco Madeira Date: Tue, 1 Oct 2024 15:01:04 +0100 Subject: [PATCH] fix: 83 | use projectInputSchema to validate project creation form (#90) Signed-off-by: Francisco Madeira --- .changeset/nice-files-wave.md | 5 + pnpm-lock.yaml | 120 +++++++++--------- web/dashboard/package.json | 2 +- .../src/components/projects/project-form.tsx | 11 +- web/dashboard/src/data/projects/dto.ts | 8 +- 5 files changed, 74 insertions(+), 72 deletions(-) create mode 100644 .changeset/nice-files-wave.md diff --git a/.changeset/nice-files-wave.md b/.changeset/nice-files-wave.md new file mode 100644 index 00000000..470cfe1a --- /dev/null +++ b/.changeset/nice-files-wave.md @@ -0,0 +1,5 @@ +--- +'@ethereal-nexus/dashboard': patch +--- + +fix: [83] use projectInputSchema to validate project creation form diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b6defaa6..f64f8c3a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -299,17 +299,17 @@ importers: specifier: ^11.10.4 version: 11.23.2 next: - specifier: 14.1.0 - version: 14.1.0(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^14.2.13 + version: 14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) next-auth: specifier: 5.0.0-beta.16 - version: 5.0.0-beta.16(next@14.1.0(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0) + version: 5.0.0-beta.16(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0) next-swagger-doc: specifier: ^0.4.0 - version: 0.4.0(next@14.1.0(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(openapi-types@12.1.3) + version: 0.4.0(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(openapi-types@12.1.3) next-themes: specifier: ^0.2.1 - version: 0.2.1(next@14.1.0(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 0.2.1(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) postgres: specifier: 3.3.5 version: 3.3.5 @@ -1903,62 +1903,62 @@ packages: '@newrelic/security-agent@1.5.0': resolution: {integrity: sha512-QCKn6WRPNgWPocD1mWwdP3kP1+U9FdOblliXaNbGA6vxXOl9NgBiFv4AgRsJxFNxwPI/6iAeA05Y454Ml8qbyQ==} - '@next/env@14.1.0': - resolution: {integrity: sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==} + '@next/env@14.2.13': + resolution: {integrity: sha512-s3lh6K8cbW1h5Nga7NNeXrbe0+2jIIYK9YaA9T7IufDWnZpozdFUp6Hf0d5rNWUKu4fEuSX2rCKlGjCrtylfDw==} '@next/eslint-plugin-next@14.2.11': resolution: {integrity: sha512-7mw+xW7Y03Ph4NTCcAzYe+vu4BNjEHZUfZayyF3Y1D9RX6c5NIe25m1grHEAkyUuaqjRxOYhnCNeglOkIqLkBA==} - '@next/swc-darwin-arm64@14.1.0': - resolution: {integrity: sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==} + '@next/swc-darwin-arm64@14.2.13': + resolution: {integrity: sha512-IkAmQEa2Htq+wHACBxOsslt+jMoV3msvxCn0WFSfJSkv/scy+i/EukBKNad36grRxywaXUYJc9mxEGkeIs8Bzg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@14.1.0': - resolution: {integrity: sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g==} + '@next/swc-darwin-x64@14.2.13': + resolution: {integrity: sha512-Dv1RBGs2TTjkwEnFMVL5XIfJEavnLqqwYSD6LXgTPdEy/u6FlSrLBSSfe1pcfqhFEXRAgVL3Wpjibe5wXJzWog==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@14.1.0': - resolution: {integrity: sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==} + '@next/swc-linux-arm64-gnu@14.2.13': + resolution: {integrity: sha512-yB1tYEFFqo4ZNWkwrJultbsw7NPAAxlPXURXioRl9SdW6aIefOLS+0TEsKrWBtbJ9moTDgU3HRILL6QBQnMevg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@14.1.0': - resolution: {integrity: sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==} + '@next/swc-linux-arm64-musl@14.2.13': + resolution: {integrity: sha512-v5jZ/FV/eHGoWhMKYrsAweQ7CWb8xsWGM/8m1mwwZQ/sutJjoFaXchwK4pX8NqwImILEvQmZWyb8pPTcP7htWg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@14.1.0': - resolution: {integrity: sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==} + '@next/swc-linux-x64-gnu@14.2.13': + resolution: {integrity: sha512-aVc7m4YL7ViiRv7SOXK3RplXzOEe/qQzRA5R2vpXboHABs3w8vtFslGTz+5tKiQzWUmTmBNVW0UQdhkKRORmGA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@14.1.0': - resolution: {integrity: sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==} + '@next/swc-linux-x64-musl@14.2.13': + resolution: {integrity: sha512-4wWY7/OsSaJOOKvMsu1Teylku7vKyTuocvDLTZQq0TYv9OjiYYWt63PiE1nTuZnqQ4RPvME7Xai+9enoiN0Wrg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@14.1.0': - resolution: {integrity: sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==} + '@next/swc-win32-arm64-msvc@14.2.13': + resolution: {integrity: sha512-uP1XkqCqV2NVH9+g2sC7qIw+w2tRbcMiXFEbMihkQ8B1+V6m28sshBwAB0SDmOe0u44ne1vFU66+gx/28RsBVQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-ia32-msvc@14.1.0': - resolution: {integrity: sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==} + '@next/swc-win32-ia32-msvc@14.2.13': + resolution: {integrity: sha512-V26ezyjPqQpDBV4lcWIh8B/QICQ4v+M5Bo9ykLN+sqeKKBxJVDpEc6biDVyluTXTC40f5IqCU0ttth7Es2ZuMw==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] - '@next/swc-win32-x64-msvc@14.1.0': - resolution: {integrity: sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==} + '@next/swc-win32-x64-msvc@14.2.13': + resolution: {integrity: sha512-WwzOEAFBGhlDHE5Z73mNU8CO8mqMNLqaG+AO9ETmzdCQlJhVtWZnOl2+rqgVQS+YHunjOWptdFmNfbpwcUuEsw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -3158,8 +3158,8 @@ packages: '@swc/helpers@0.5.13': resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} - '@swc/helpers@0.5.2': - resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==} + '@swc/helpers@0.5.5': + resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} '@swc/types@0.1.12': resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} @@ -6495,18 +6495,21 @@ packages: next-tick@1.1.0: resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} - next@14.1.0: - resolution: {integrity: sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q==} + next@14.2.13: + resolution: {integrity: sha512-BseY9YNw8QJSwLYD7hlZzl6QVDoSFHL/URN5K64kVEVpCsSOWeyjbIGK+dZUaRViHTaMQX8aqmnn0PHBbGZezg==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 react: ^18.2.0 react-dom: ^18.2.0 sass: ^1.3.0 peerDependenciesMeta: '@opentelemetry/api': optional: true + '@playwright/test': + optional: true sass: optional: true @@ -10456,37 +10459,37 @@ snapshots: - supports-color - utf-8-validate - '@next/env@14.1.0': {} + '@next/env@14.2.13': {} '@next/eslint-plugin-next@14.2.11': dependencies: glob: 10.3.10 - '@next/swc-darwin-arm64@14.1.0': + '@next/swc-darwin-arm64@14.2.13': optional: true - '@next/swc-darwin-x64@14.1.0': + '@next/swc-darwin-x64@14.2.13': optional: true - '@next/swc-linux-arm64-gnu@14.1.0': + '@next/swc-linux-arm64-gnu@14.2.13': optional: true - '@next/swc-linux-arm64-musl@14.1.0': + '@next/swc-linux-arm64-musl@14.2.13': optional: true - '@next/swc-linux-x64-gnu@14.1.0': + '@next/swc-linux-x64-gnu@14.2.13': optional: true - '@next/swc-linux-x64-musl@14.1.0': + '@next/swc-linux-x64-musl@14.2.13': optional: true - '@next/swc-win32-arm64-msvc@14.1.0': + '@next/swc-win32-arm64-msvc@14.2.13': optional: true - '@next/swc-win32-ia32-msvc@14.1.0': + '@next/swc-win32-ia32-msvc@14.2.13': optional: true - '@next/swc-win32-x64-msvc@14.1.0': + '@next/swc-win32-x64-msvc@14.2.13': optional: true '@nodelib/fs.scandir@2.1.5': @@ -11894,8 +11897,9 @@ snapshots: tslib: 2.7.0 optional: true - '@swc/helpers@0.5.2': + '@swc/helpers@0.5.5': dependencies: + '@swc/counter': 0.1.3 tslib: 2.7.0 '@swc/types@0.1.12': @@ -16419,34 +16423,34 @@ snapshots: - supports-color - utf-8-validate - next-auth@5.0.0-beta.16(next@14.1.0(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0): + next-auth@5.0.0-beta.16(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0): dependencies: '@auth/core': 0.28.1 - next: 14.1.0(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + next: 14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 - next-swagger-doc@0.4.0(next@14.1.0(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(openapi-types@12.1.3): + next-swagger-doc@0.4.0(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(openapi-types@12.1.3): dependencies: '@types/swagger-jsdoc': 6.0.1 cleye: 1.3.2 isarray: 2.0.5 - next: 14.1.0(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + next: 14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) swagger-jsdoc: 6.2.8(openapi-types@12.1.3) transitivePeerDependencies: - openapi-types - next-themes@0.2.1(next@14.1.0(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + next-themes@0.2.1(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: - next: 14.1.0(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + next: 14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) next-tick@1.1.0: {} - next@14.1.0(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: - '@next/env': 14.1.0 - '@swc/helpers': 0.5.2 + '@next/env': 14.2.13 + '@swc/helpers': 0.5.5 busboy: 1.6.0 caniuse-lite: 1.0.30001660 graceful-fs: 4.2.11 @@ -16455,15 +16459,15 @@ snapshots: react-dom: 18.2.0(react@18.2.0) styled-jsx: 5.1.1(@babel/core@7.25.2)(react@18.2.0) optionalDependencies: - '@next/swc-darwin-arm64': 14.1.0 - '@next/swc-darwin-x64': 14.1.0 - '@next/swc-linux-arm64-gnu': 14.1.0 - '@next/swc-linux-arm64-musl': 14.1.0 - '@next/swc-linux-x64-gnu': 14.1.0 - '@next/swc-linux-x64-musl': 14.1.0 - '@next/swc-win32-arm64-msvc': 14.1.0 - '@next/swc-win32-ia32-msvc': 14.1.0 - '@next/swc-win32-x64-msvc': 14.1.0 + '@next/swc-darwin-arm64': 14.2.13 + '@next/swc-darwin-x64': 14.2.13 + '@next/swc-linux-arm64-gnu': 14.2.13 + '@next/swc-linux-arm64-musl': 14.2.13 + '@next/swc-linux-x64-gnu': 14.2.13 + '@next/swc-linux-x64-musl': 14.2.13 + '@next/swc-win32-arm64-msvc': 14.2.13 + '@next/swc-win32-ia32-msvc': 14.2.13 + '@next/swc-win32-x64-msvc': 14.2.13 '@opentelemetry/api': 1.9.0 transitivePeerDependencies: - '@babel/core' diff --git a/web/dashboard/package.json b/web/dashboard/package.json index c64de86d..570c353a 100644 --- a/web/dashboard/package.json +++ b/web/dashboard/package.json @@ -46,7 +46,7 @@ "gunzip-maybe": "^1.4.2", "lucide-react": "^0.274.0", "newrelic": "^11.10.4", - "next": "14.1.0", + "next": "^14.2.13", "next-auth": "5.0.0-beta.16", "next-swagger-doc": "^0.4.0", "next-themes": "^0.2.1", diff --git a/web/dashboard/src/components/projects/project-form.tsx b/web/dashboard/src/components/projects/project-form.tsx index ba31290c..3e1e5d48 100644 --- a/web/dashboard/src/components/projects/project-form.tsx +++ b/web/dashboard/src/components/projects/project-form.tsx @@ -10,17 +10,10 @@ import {TextArea} from '@/components/ui/text-area'; import {zodResolver} from "@hookform/resolvers/zod"; import React from "react"; import { useToast } from '@/components/ui/use-toast'; -import { ProjectInput } from '@/data/projects/dto'; +import { ProjectInput, projectInputSchema } from '@/data/projects/dto'; import { upsertProject } from '@/data/projects/actions'; import { useSession } from 'next-auth/react'; -const projectsFormSchema = z.object({ - name: z.string().min(3, { - message: "Name must be at least 3 characters.", - }), - description: z.string(), -}); - type ProjectsFormProps = { project?: ProjectInput, onComplete?: () => void, @@ -31,7 +24,7 @@ export default function ProjectsForm({project, onComplete, onCancel}: ProjectsFo const {data: session} = useSession(); const { toast } = useToast() const form: any = useForm({ - resolver: zodResolver(projectsFormSchema), + resolver: zodResolver(projectInputSchema), defaultValues: project ?? {}, }); const onSubmit = async (data: ProjectInput) => { diff --git a/web/dashboard/src/data/projects/dto.ts b/web/dashboard/src/data/projects/dto.ts index c9f5f0af..63aa35bb 100644 --- a/web/dashboard/src/data/projects/dto.ts +++ b/web/dashboard/src/data/projects/dto.ts @@ -59,7 +59,7 @@ export type ProjectComponentConfig = z.infer< */ export const projectWithComponentIdSchema = projectSchema.extend({ components: projectComponentConfigSchema.pick({ component_id: true }).array(), - environments: environmentsSchema.pick({id: true, name: true}).array() + environments: environmentsSchema.pick({ id: true, name: true }).array() }); export type ProjectWithComponentId = z.infer< typeof projectWithComponentIdSchema @@ -148,7 +148,7 @@ export const projectInputSchema = createInsertSchema(projects, { name: (schema) => schema.name.min(4, 'Name must be longer than 4 characters.') }) - .required({ name: true }); + .required({ name: true, description: true }); export type ProjectInput = z.infer; export const projectComponentConfigInputSchema = createInsertSchema( @@ -169,11 +169,11 @@ export const environmentWithComponentsSchema = environmentsSchema.extend({ components: componentsSchema.pick({ id: true, name: true, - title: true, + title: true }).extend({ config_id: projectComponentConfigSchema.shape.id, is_active: projectComponentConfigSchema.shape.is_active, - version: componentVersionsSchema.shape.version.nullable(), + version: componentVersionsSchema.shape.version.nullable() }).array() }); export type EnvironmentWithComponents = z.infer;