diff --git a/.env.example b/.env.example index 1a4c51ccf9..db986396c9 100644 --- a/.env.example +++ b/.env.example @@ -104,8 +104,8 @@ NEXT_PUBLIC_FORMBRICKS_ONBOARDING_SURVEY_ID= # Cron Secret CRON_SECRET= -*/ # Encryption key # You can use: `openssl rand -base64 16` to generate one -FORMBRICKS_ENCRYPTION_KEY= \ No newline at end of file +FORMBRICKS_ENCRYPTION_KEY= +*/ diff --git a/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/actions/actions.ts b/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/actions/actions.ts index 0a82437d09..fc739ff3e0 100644 --- a/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/actions/actions.ts +++ b/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/actions/actions.ts @@ -11,7 +11,7 @@ import { getActionCountInLast24Hours, getActionCountInLast7Days, getActionCountInLastHour, -} from "@formbricks/lib/services/actions"; +} from "@formbricks/lib/action/service"; import { getSurveysByActionClassId } from "@formbricks/lib/survey/service"; import { AuthorizationError } from "@formbricks/types/v1/errors"; diff --git a/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/AttributeSettingsTab.tsx b/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/AttributeSettingsTab.tsx index 55e1d4d86c..2360b75b2c 100644 --- a/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/AttributeSettingsTab.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/AttributeSettingsTab.tsx @@ -5,7 +5,7 @@ import type { AttributeClass } from "@prisma/client"; import { useForm } from "react-hook-form"; import { ArchiveBoxArrowDownIcon, ArchiveBoxXMarkIcon } from "@heroicons/react/24/solid"; import { useRouter } from "next/navigation"; -import { updatetAttributeClass } from "@formbricks/lib/services/attributeClass"; +import { updatetAttributeClass } from "@formbricks/lib/attributeClass/service"; import { useState } from "react"; interface AttributeSettingsTabProps { diff --git a/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/page.tsx b/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/page.tsx index 6a37ff53bf..6eda4be838 100644 --- a/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/page.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/page.tsx @@ -5,7 +5,7 @@ import AttributeClassDataRow from "@/app/(app)/environments/[environmentId]/(act import AttributeTableHeading from "@/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/AttributeTableHeading"; import HowToAddAttributesButton from "@/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/HowToAddAttributesButton"; import { REVALIDATION_INTERVAL } from "@formbricks/lib/constants"; -import { getAttributeClasses } from "@formbricks/lib/services/attributeClass"; +import { getAttributeClasses } from "@formbricks/lib/attributeClass/service"; import { Metadata } from "next"; export const metadata: Metadata = { diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/setup/page.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/setup/page.tsx index 904069d470..a850c80ea5 100644 --- a/apps/web/app/(app)/environments/[environmentId]/settings/setup/page.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/settings/setup/page.tsx @@ -4,7 +4,7 @@ import { updateEnvironmentAction } from "@/app/(app)/environments/[environmentId import EnvironmentNotice from "@/components/shared/EnvironmentNotice"; import WidgetStatusIndicator from "@/components/shared/WidgetStatusIndicator"; import { REVALIDATION_INTERVAL } from "@formbricks/lib/constants"; -import { getActionsByEnvironmentId } from "@formbricks/lib/services/actions"; +import { getActionsByEnvironmentId } from "@formbricks/lib/action/service"; import { getEnvironment } from "@formbricks/lib/services/environment"; import { ErrorComponent } from "@formbricks/ui"; import SettingsCard from "../SettingsCard"; diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/LinkSingleUseSurveyModal.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/LinkSingleUseSurveyModal.tsx index 422aae3de2..de51ea6395 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/LinkSingleUseSurveyModal.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/LinkSingleUseSurveyModal.tsx @@ -109,7 +109,7 @@ export default function LinkSingleUseSurveyModal({ title="Preview survey" aria-label="Preview survey" className="flex justify-center" - href={`${defaultSurveyUrl}?suId=${singleUseIds[0]}preview=true`} + href={`${defaultSurveyUrl}?suId=${singleUseIds[0]}&preview=true`} target="_blank" EndIcon={EyeIcon}> Preview diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/LogicEditor.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/LogicEditor.tsx index 386d43fb88..c5b8b20f28 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/LogicEditor.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/LogicEditor.tsx @@ -20,6 +20,7 @@ import { import { QuestionMarkCircleIcon, TrashIcon } from "@heroicons/react/24/solid"; import { ChevronDown, SplitIcon } from "lucide-react"; import { useMemo } from "react"; +import { toast } from "react-hot-toast"; import { BsArrowDown, BsArrowReturnRight } from "react-icons/bs"; interface LogicEditorProps { @@ -141,6 +142,19 @@ export default function LogicEditor({ }; const addLogic = () => { + if (question.logic && question.logic?.length >= 0) { + const hasUndefinedLogic = question.logic.some( + (logic) => + logic.condition === undefined && logic.value === undefined && logic.destination === undefined + ); + if (hasUndefinedLogic) { + toast("Please fill current logic jumps first.", { + icon: "🤓", + }); + return; + } + } + const newLogic: TSurveyLogic[] = !question.logic ? [] : question.logic; newLogic.push({ condition: undefined, diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/MultipleChoiceMultiForm.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/MultipleChoiceMultiForm.tsx index e8efe2bbd0..30e121b28e 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/MultipleChoiceMultiForm.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/MultipleChoiceMultiForm.tsx @@ -33,6 +33,7 @@ export default function MultipleChoiceMultiForm({ const [isNew, setIsNew] = useState(true); const [showSubheader, setShowSubheader] = useState(!!question.subheader); const questionRef = useRef(null); + const [isInvalidValue, setIsInvalidValue] = useState(null); const shuffleOptionsTypes = { none: { @@ -76,6 +77,24 @@ export default function MultipleChoiceMultiForm({ updateQuestion(questionIdx, { choices: newChoices, logic: newLogic }); }; + const findDuplicateLabel = () => { + for (let i = 0; i < question.choices.length; i++) { + for (let j = i + 1; j < question.choices.length; j++) { + if (question.choices[i].label.trim() === question.choices[j].label.trim()) { + return question.choices[i].label.trim(); // Return the duplicate label + } + } + } + return null; + }; + + const findEmptyLabel = () => { + for (let i = 0; i < question.choices.length; i++) { + if (question.choices[i].label.trim() === "") return true; + } + return false; + }; + const addChoice = (choiceIdx?: number) => { setIsNew(false); // This question is no longer new. let newChoices = !question.choices ? [] : question.choices; @@ -112,6 +131,9 @@ export default function MultipleChoiceMultiForm({ const newChoices = !question.choices ? [] : question.choices.filter((_, idx) => idx !== choiceIdx); const choiceValue = question.choices[choiceIdx].label; + if (isInvalidValue === choiceValue) { + setIsInvalidValue(null); + } let newLogic: any[] = []; question.logic?.forEach((logic) => { let newL: string | string[] | undefined = logic.value; @@ -198,7 +220,20 @@ export default function MultipleChoiceMultiForm({ className={cn(choice.id === "other" && "border-dashed")} placeholder={choice.id === "other" ? "Other" : `Option ${choiceIdx + 1}`} onChange={(e) => updateChoice(choiceIdx, { label: e.target.value })} - isInvalid={isInValid && choice.label.trim() === ""} + onBlur={() => { + const duplicateLabel = findDuplicateLabel(); + if (duplicateLabel) { + setIsInvalidValue(duplicateLabel); + } else if (findEmptyLabel()) { + setIsInvalidValue(""); + } else { + setIsInvalidValue(null); + } + }} + isInvalid={ + (isInvalidValue === "" && choice.label.trim() === "") || + (isInvalidValue !== null && choice.label.trim() === isInvalidValue.trim()) + } /> {question.choices && question.choices.length > 2 && ( (null); const [isNew, setIsNew] = useState(true); const [showSubheader, setShowSubheader] = useState(!!question.subheader); + const [isInvalidValue, setIsInvalidValue] = useState(null); const questionRef = useRef(null); const shuffleOptionsTypes = { @@ -52,6 +53,24 @@ export default function MultipleChoiceSingleForm({ }, }; + const findDuplicateLabel = () => { + for (let i = 0; i < question.choices.length; i++) { + for (let j = i + 1; j < question.choices.length; j++) { + if (question.choices[i].label.trim() === question.choices[j].label.trim()) { + return question.choices[i].label.trim(); // Return the duplicate label + } + } + } + return null; + }; + + const findEmptyLabel = () => { + for (let i = 0; i < question.choices.length; i++) { + if (question.choices[i].label.trim() === "") return true; + } + return false; + }; + const updateChoice = (choiceIdx: number, updatedAttributes: { label: string }) => { const newLabel = updatedAttributes.label; const oldLabel = question.choices[choiceIdx].label; @@ -112,6 +131,9 @@ export default function MultipleChoiceSingleForm({ const newChoices = !question.choices ? [] : question.choices.filter((_, idx) => idx !== choiceIdx); const choiceValue = question.choices[choiceIdx].label; + if (isInvalidValue === choiceValue) { + setIsInvalidValue(null); + } let newLogic: any[] = []; question.logic?.forEach((logic) => { let newL: string | string[] | undefined = logic.value; @@ -197,8 +219,21 @@ export default function MultipleChoiceSingleForm({ value={choice.label} className={cn(choice.id === "other" && "border-dashed")} placeholder={choice.id === "other" ? "Other" : `Option ${choiceIdx + 1}`} + onBlur={() => { + const duplicateLabel = findDuplicateLabel(); + if (duplicateLabel) { + setIsInvalidValue(duplicateLabel); + } else if (findEmptyLabel()) { + setIsInvalidValue(""); + } else { + setIsInvalidValue(null); + } + }} onChange={(e) => updateChoice(choiceIdx, { label: e.target.value })} - isInvalid={isInValid && choice.label.trim() === ""} + isInvalid={ + (isInvalidValue === "" && choice.label.trim() === "") || + (isInvalidValue !== null && choice.label.trim() === isInvalidValue.trim()) + } /> {question.choices && question.choices.length > 2 && ( void; + className?: string; +}) { return (
@@ -53,6 +61,7 @@ export function BackButtonInput({ value, onChange }) { value={value} placeholder="Back" onChange={onChange} + className={className} />
@@ -235,9 +244,24 @@ export default function QuestionCard({ updateQuestion(questionIdx, { buttonLabel: e.target.value })} + onChange={(e) => { + const trimmedValue = e.target.value.trim(); // Remove spaces from the start and end + const hasInternalSpaces = /\S\s\S/.test(trimmedValue); // Test if there are spaces between words + + if ( + !trimmedValue.includes(" ") && + (trimmedValue === "" || hasInternalSpaces || !/\s/.test(trimmedValue)) + ) { + updateQuestion(questionIdx, { backButtonLabel: trimmedValue }); + } + }} /> @@ -245,6 +269,11 @@ export default function QuestionCard({ updateQuestion(questionIdx, { backButtonLabel: e.target.value })} + className={cn( + isInValid && + question.backButtonLabel?.trim() === "" && + "border border-red-600 focus:border-red-600" + )} /> )} @@ -255,6 +284,11 @@ export default function QuestionCard({ updateQuestion(questionIdx, { backButtonLabel: e.target.value })} + className={cn( + isInValid && + question.backButtonLabel?.trim() === "" && + "border border-red-600 focus:border-red-600" + )} /> )} diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/SurveyMenuBar.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/SurveyMenuBar.tsx index b0f9bd0378..3291268377 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/SurveyMenuBar.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/SurveyMenuBar.tsx @@ -3,6 +3,7 @@ import AlertDialog from "@/components/shared/AlertDialog"; import DeleteDialog from "@/components/shared/DeleteDialog"; import SurveyStatusDropdown from "@/components/shared/SurveyStatusDropdown"; +import { QuestionType } from "@formbricks/types/questions"; import type { Survey } from "@formbricks/types/surveys"; import { TEnvironment } from "@formbricks/types/v1/environment"; import { TProduct } from "@formbricks/types/v1/product"; @@ -97,6 +98,14 @@ export default function SurveyMenuBar({ }; const validateSurvey = (survey) => { + const existingLogicConditions = new Set(); + const existingQuestionIds = new Set(); + + if (survey.questions.length === 0) { + toast.error("Please add at least one question"); + return; + } + faultyQuestions = []; for (let index = 0; index < survey.questions.length; index++) { const question = survey.questions[index]; @@ -109,7 +118,67 @@ export default function SurveyMenuBar({ // if there are any faulty questions, the user won't be allowed to save the survey if (faultyQuestions.length > 0) { setInvalidQuestions(faultyQuestions); - toast.error("Please fill required fields"); + toast.error("Please fill all required fields."); + return false; + } + + for (const question of survey.questions) { + if (existingQuestionIds.has(question.id)) { + toast.error("There are 2 identical question IDs. Please update one."); + return false; + } + existingQuestionIds.add(question.id); + + if ( + question.type === QuestionType.MultipleChoiceSingle || + question.type === QuestionType.MultipleChoiceMulti + ) { + const haveSameChoices = + question.choices.some((element) => element.label.trim() === "") || + question.choices.some((element, index) => + question.choices + .slice(index + 1) + .some((nextElement) => nextElement.label.trim() === element.label.trim()) + ); + + if (haveSameChoices) { + toast.error("You have two identical choices."); + return false; + } + } + + for (const logic of question.logic || []) { + const validFields = ["condition", "destination", "value"].filter( + (field) => logic[field] !== undefined + ).length; + + if (validFields < 2) { + setInvalidQuestions([question.id]); + toast.error("Incomplete logic jumps detected: Please fill or delete them."); + return false; + } + + if (question.required && logic.condition === "skipped") { + toast.error("You have a missing logic condition. Please update or delete it."); + return false; + } + + const thisLogic = `${logic.condition}-${logic.value}`; + if (existingLogicConditions.has(thisLogic)) { + setInvalidQuestions([question.id]); + toast.error("You have 2 competing logic conditons. Please update or delete one."); + return false; + } + existingLogicConditions.add(thisLogic); + } + } + + if ( + survey.redirectUrl && + !survey.redirectUrl.includes("https://") && + !survey.redirectUrl.includes("http://") + ) { + toast.error("Please enter a valid URL for redirecting respondents."); return false; } @@ -128,6 +197,10 @@ export default function SurveyMenuBar({ }; const saveSurveyAction = async (shouldNavigateBack = false) => { + if (localSurvey.questions.length === 0) { + toast.error("Please add at least one question."); + return; + } setIsMutatingSurvey(true); // Create a copy of localSurvey with isDraft removed from every question const strippedSurvey: TSurvey = { @@ -139,6 +212,7 @@ export default function SurveyMenuBar({ }; if (!validateSurvey(localSurvey)) { + setIsMutatingSurvey(false); return; } @@ -240,6 +314,7 @@ export default function SurveyMenuBar({ onClick={async () => { setIsMutatingSurvey(true); if (!validateSurvey(localSurvey)) { + setIsMutatingSurvey(false); return; } await updateSurveyAction({ ...localSurvey, status: "inProgress" }); diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/UpdateQuestionId.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/UpdateQuestionId.tsx index 1b18a11d26..08650618e8 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/UpdateQuestionId.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/UpdateQuestionId.tsx @@ -7,6 +7,9 @@ import toast from "react-hot-toast"; export default function UpdateQuestionId({ localSurvey, question, questionIdx, updateQuestion }) { const [currentValue, setCurrentValue] = useState(question.id); const [prevValue, setPrevValue] = useState(question.id); + const [isInputInvalid, setIsInputInvalid] = useState( + currentValue.trim() === "" || currentValue.includes(" ") + ); const saveAction = () => { // return early if the input value was not changed @@ -14,28 +17,22 @@ export default function UpdateQuestionId({ localSurvey, question, questionIdx, u return; } - // check if id is unique const questionIds = localSurvey.questions.map((q) => q.id); if (questionIds.includes(currentValue)) { + setIsInputInvalid(true); toast.error("IDs have to be unique per survey."); - setCurrentValue(question.id); - return; - } - - // check if id contains any spaces - if (currentValue.trim() === "" || currentValue.includes(" ")) { - toast.error("ID should not contain space."); - setCurrentValue(question.id); - return; + } else if (currentValue.trim() === "" || currentValue.includes(" ")) { + setIsInputInvalid(true); + toast.error("ID should not be empty."); + } else { + setIsInputInvalid(false); + toast.success("Question ID updated."); } updateQuestion(questionIdx, { id: currentValue }); - toast.success("Question ID updated."); setPrevValue(currentValue); // after successful update, set current value as previous value }; - const isInputInvalid = currentValue.trim() === "" || currentValue.includes(" "); - return (
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/Validation.ts b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/Validation.ts index a2830b8f50..09eb880cf7 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/Validation.ts +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/Validation.ts @@ -1,6 +1,7 @@ // extend this object in order to add more validation rules import { + TSurveyConsentQuestion, TSurveyMultipleChoiceMultiQuestion, TSurveyMultipleChoiceSingleQuestion, TSurveyQuestion, @@ -13,8 +14,16 @@ const validationRules = { multipleChoiceSingle: (question: TSurveyMultipleChoiceSingleQuestion) => { return !question.choices.some((element) => element.label.trim() === ""); }, + consent: (question: TSurveyConsentQuestion) => { + return question.label.trim() !== ""; + }, defaultValidation: (question: TSurveyQuestion) => { - return question.headline.trim() !== ""; + console.log(question); + return ( + question.headline.trim() !== "" && + question.buttonLabel?.trim() !== "" && + question.backButtonLabel?.trim() !== "" + ); }, }; diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/page.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/page.tsx index fd18a81945..846e0ba128 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/page.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/page.tsx @@ -6,7 +6,7 @@ import { getSurveyWithAnalytics } from "@formbricks/lib/survey/service"; import { getProductByEnvironmentId } from "@formbricks/lib/services/product"; import { getEnvironment } from "@formbricks/lib/services/environment"; import { getActionClasses } from "@formbricks/lib/actionClass/service"; -import { getAttributeClasses } from "@formbricks/lib/services/attributeClass"; +import { getAttributeClasses } from "@formbricks/lib/attributeClass/service"; import { ErrorComponent } from "@formbricks/ui"; export default async function SurveysEditPage({ params }) { diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/page.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/page.tsx index 377d4a90e2..18ad886b6f 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/page.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/page.tsx @@ -4,7 +4,7 @@ import { updateEnvironmentAction } from "@/app/(app)/environments/[environmentId import ContentWrapper from "@/components/shared/ContentWrapper"; import WidgetStatusIndicator from "@/components/shared/WidgetStatusIndicator"; import { REVALIDATION_INTERVAL } from "@formbricks/lib/constants"; -import { getActionsByEnvironmentId } from "@formbricks/lib/services/actions"; +import { getActionsByEnvironmentId } from "@formbricks/lib/action/service"; import { getEnvironment } from "@formbricks/lib/services/environment"; import { Metadata } from "next"; import SurveysList from "./SurveyList"; diff --git a/apps/web/app/api/v1/client/displays/[displayId]/responded/route.ts b/apps/web/app/api/v1/client/displays/[displayId]/responded/route.ts index 8901832fc4..c9d6710216 100644 --- a/apps/web/app/api/v1/client/displays/[displayId]/responded/route.ts +++ b/apps/web/app/api/v1/client/displays/[displayId]/responded/route.ts @@ -1,5 +1,5 @@ import { responses } from "@/lib/api/response"; -import { markDisplayResponded } from "@formbricks/lib/services/displays"; +import { markDisplayResponded } from "@formbricks/lib/display/service"; import { NextResponse } from "next/server"; export async function OPTIONS(): Promise { diff --git a/apps/web/app/api/v1/client/displays/route.ts b/apps/web/app/api/v1/client/displays/route.ts index 7d46e99a8e..9ac23ee5b2 100644 --- a/apps/web/app/api/v1/client/displays/route.ts +++ b/apps/web/app/api/v1/client/displays/route.ts @@ -2,7 +2,7 @@ import { responses } from "@/lib/api/response"; import { transformErrorToDetails } from "@/lib/api/validator"; import { InvalidInputError } from "@formbricks/types/v1/errors"; import { capturePosthogEvent } from "@formbricks/lib/posthogServer"; -import { createDisplay } from "@formbricks/lib/services/displays"; +import { createDisplay } from "@formbricks/lib/display/service"; import { getSurvey } from "@formbricks/lib/survey/service"; import { getTeamDetails } from "@formbricks/lib/services/teamDetails"; import { TDisplay, ZDisplayInput } from "@formbricks/types/v1/displays"; diff --git a/apps/web/app/api/v1/js/actions/route.ts b/apps/web/app/api/v1/js/actions/route.ts index 883f95260c..f5fcdc1ff2 100644 --- a/apps/web/app/api/v1/js/actions/route.ts +++ b/apps/web/app/api/v1/js/actions/route.ts @@ -1,6 +1,6 @@ import { responses } from "@/lib/api/response"; import { transformErrorToDetails } from "@/lib/api/validator"; -import { createAction } from "@formbricks/lib/services/actions"; +import { createAction } from "@formbricks/lib/action/service"; import { ZJsActionInput } from "@formbricks/types/v1/js"; import { NextResponse } from "next/server"; diff --git a/apps/web/app/api/v1/js/people/[personId]/set-attribute/route.ts b/apps/web/app/api/v1/js/people/[personId]/set-attribute/route.ts index 10cafc9191..6d959707cc 100644 --- a/apps/web/app/api/v1/js/people/[personId]/set-attribute/route.ts +++ b/apps/web/app/api/v1/js/people/[personId]/set-attribute/route.ts @@ -1,7 +1,7 @@ import { getUpdatedState } from "@/app/api/v1/js/sync/lib/sync"; import { responses } from "@/lib/api/response"; import { transformErrorToDetails } from "@/lib/api/validator"; -import { createAttributeClass, getAttributeClassByNameCached } from "@formbricks/lib/services/attributeClass"; +import { createAttributeClass, getAttributeClassByNameCached } from "@formbricks/lib/attributeClass/service"; import { getPersonCached, updatePersonAttribute } from "@formbricks/lib/services/person"; import { ZJsPeopleAttributeInput } from "@formbricks/types/v1/js"; import { NextResponse } from "next/server"; diff --git a/apps/web/app/api/v1/management/attribute-classes/[attributeClassId]/route.ts b/apps/web/app/api/v1/management/attribute-classes/[attributeClassId]/route.ts index f46f0145f9..fe2363263d 100644 --- a/apps/web/app/api/v1/management/attribute-classes/[attributeClassId]/route.ts +++ b/apps/web/app/api/v1/management/attribute-classes/[attributeClassId]/route.ts @@ -5,7 +5,7 @@ import { deleteAttributeClass, getAttributeClass, updatetAttributeClass, -} from "@formbricks/lib/services/attributeClass"; +} from "@formbricks/lib/attributeClass/service"; import { TAttributeClass, ZAttributeClassUpdateInput } from "@formbricks/types/v1/attributeClasses"; import { transformErrorToDetails } from "@/lib/api/validator"; import { authenticateRequest } from "@/app/api/v1/auth"; diff --git a/apps/web/app/api/v1/management/attribute-classes/route.ts b/apps/web/app/api/v1/management/attribute-classes/route.ts index ca0b33f2c6..48a5aeb8d1 100644 --- a/apps/web/app/api/v1/management/attribute-classes/route.ts +++ b/apps/web/app/api/v1/management/attribute-classes/route.ts @@ -4,7 +4,7 @@ import { authenticateRequest } from "@/app/api/v1/auth"; import { NextResponse } from "next/server"; import { transformErrorToDetails } from "@/lib/api/validator"; import { TAttributeClass, ZAttributeClassInput } from "@formbricks/types/v1/attributeClasses"; -import { createAttributeClass, getAttributeClasses } from "@formbricks/lib/services/attributeClass"; +import { createAttributeClass, getAttributeClasses } from "@formbricks/lib/attributeClass/service"; export async function GET(request: Request) { try { diff --git a/packages/database/package.json b/packages/database/package.json index 441f505e79..61f20cc9e4 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -36,7 +36,7 @@ "prisma": "^5.3.1", "prisma-dbml-generator": "^0.10.0", "prisma-json-types-generator": "^3.0.1", - "zod": "^3.22.2", + "zod": "^3.22.3", "zod-prisma": "^0.5.4" } } diff --git a/packages/lib/services/actions.ts b/packages/lib/action/service.ts similarity index 96% rename from packages/lib/services/actions.ts rename to packages/lib/action/service.ts index ffa8b2475a..08038ba032 100644 --- a/packages/lib/services/actions.ts +++ b/packages/lib/action/service.ts @@ -2,7 +2,7 @@ import "server-only"; import z from "zod"; import { prisma } from "@formbricks/database"; -import { DatabaseError } from "@formbricks/types/v1/errors"; +import { DatabaseError, ResourceNotFoundError } from "@formbricks/types/v1/errors"; import { TAction } from "@formbricks/types/v1/actions"; import { ZId } from "@formbricks/types/v1/environment"; import { Prisma } from "@prisma/client"; @@ -65,7 +65,7 @@ export const createAction = async (data: TJsActionInput) => { const session = await getSessionCached(sessionId); if (!session) { - throw new Error("Session not found"); + throw new ResourceNotFoundError("Session", sessionId); } const actionClass = await getActionClassCached(name, environmentId); diff --git a/packages/lib/services/attributeClass.ts b/packages/lib/attributeClass/service.ts similarity index 100% rename from packages/lib/services/attributeClass.ts rename to packages/lib/attributeClass/service.ts diff --git a/packages/lib/services/displays.ts b/packages/lib/display/service.ts similarity index 98% rename from packages/lib/services/displays.ts rename to packages/lib/display/service.ts index 5cbe1983d9..82125f2a81 100644 --- a/packages/lib/services/displays.ts +++ b/packages/lib/display/service.ts @@ -13,7 +13,7 @@ import { Prisma } from "@prisma/client"; import { revalidateTag } from "next/cache"; import { cache } from "react"; import { validateInputs } from "../utils/validate"; -import { transformPrismaPerson } from "./person"; +import { transformPrismaPerson } from "../services/person"; const selectDisplay = { id: true, diff --git a/packages/lib/services/activity.tsx b/packages/lib/services/activity.tsx index 55ba044ffd..c9215812f6 100644 --- a/packages/lib/services/activity.tsx +++ b/packages/lib/services/activity.tsx @@ -5,6 +5,7 @@ import { TActivityFeedItem } from "@formbricks/types/v1/activity"; import { validateInputs } from "../utils/validate"; import { ZId } from "@formbricks/types/v1/environment"; import { cache } from "react"; +import { ResourceNotFoundError } from "@formbricks/types/v1/errors"; export const getActivityTimeline = cache(async (personId: string): Promise => { validateInputs([personId, ZId]); @@ -34,8 +35,9 @@ export const getActivityTimeline = cache(async (personId: string): Promise { if (err) { - throw new Error(`Error while appending data: ${err.message}`); - } else { + throw new UnknownError(`Error while appending data: ${err.message}`); } } ); @@ -104,8 +103,7 @@ export async function writeData(credentials: TGoogleCredential, spreadsheetId: s }, (err: Error) => { if (err) { - throw new Error(`Error while appending data: ${err.message}`); - } else { + throw new UnknownError(`Error while appending data: ${err.message}`); } } ); diff --git a/packages/lib/services/membership.ts b/packages/lib/services/membership.ts index 16f0123aaa..470cc72280 100644 --- a/packages/lib/services/membership.ts +++ b/packages/lib/services/membership.ts @@ -1,7 +1,7 @@ import "server-only"; import { prisma } from "@formbricks/database"; -import { ResourceNotFoundError } from "@formbricks/types/v1/errors"; +import { ResourceNotFoundError, DatabaseError, UnknownError } from "@formbricks/types/v1/errors"; import { TMember, TMembership, TMembershipUpdateInput } from "@formbricks/types/v1/memberships"; import { Prisma } from "@prisma/client"; import { cache } from "react"; @@ -102,9 +102,9 @@ export const updateMembership = async ( } catch (error) { if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2016") { throw new ResourceNotFoundError("Membership", `userId: ${userId}, teamId: ${teamId}`); - } else { - throw error; // Re-throw any other errors } + + throw error; } }; @@ -148,6 +148,11 @@ export const transferOwnership = async (currentOwnerId: string, newOwnerId: stri }), ]); } catch (error) { - throw new Error("Something went wrong"); + if (error instanceof Prisma.PrismaClientKnownRequestError) { + throw new DatabaseError("Database operation failed"); + } + + const message = error instanceof Error ? error.message : ""; + throw new UnknownError(`Error while transfering ownership: ${message}`); } }; diff --git a/packages/lib/services/person.ts b/packages/lib/services/person.ts index bc2ca3f203..ae5bb4c0b2 100644 --- a/packages/lib/services/person.ts +++ b/packages/lib/services/person.ts @@ -2,14 +2,14 @@ import "server-only"; import { prisma } from "@formbricks/database"; import { ZId } from "@formbricks/types/v1/environment"; -import { DatabaseError } from "@formbricks/types/v1/errors"; +import { DatabaseError, ResourceNotFoundError } from "@formbricks/types/v1/errors"; import { TPerson, TPersonUpdateInput } from "@formbricks/types/v1/people"; import { Prisma } from "@prisma/client"; import { revalidateTag, unstable_cache } from "next/cache"; import { cache } from "react"; import { PEOPLE_PER_PAGE } from "../constants"; import { validateInputs } from "../utils/validate"; -import { getAttributeClassByName } from "./attributeClass"; +import { getAttributeClassByName } from "../attributeClass/service"; import { SERVICES_REVALIDATION_INTERVAL } from "../constants"; export const selectPerson = { @@ -250,7 +250,7 @@ export const getOrCreatePersonByUserId = async (userId: string, environmentId: s const userIdAttributeClass = await getAttributeClassByName(environmentId, "userId"); if (!userIdAttributeClass) { - throw new Error("Attribute class not found for the given environmentId"); + throw new ResourceNotFoundError("Attribute class not found for the given environment", environmentId); } const personPrisma = await prisma.person.create({ diff --git a/packages/lib/services/team.ts b/packages/lib/services/team.ts index 63883dca4b..c7371ecc83 100644 --- a/packages/lib/services/team.ts +++ b/packages/lib/services/team.ts @@ -2,7 +2,7 @@ import "server-only"; import { prisma } from "@formbricks/database"; import { ZId } from "@formbricks/types/v1/environment"; -import { DatabaseError, ResourceNotFoundError } from "@formbricks/types/v1/errors"; +import { DatabaseError, ResourceNotFoundError, ValidationError } from "@formbricks/types/v1/errors"; import { TTeam, TTeamUpdateInput } from "@formbricks/types/v1/teams"; import { createId } from "@paralleldrive/cuid2"; import { Prisma } from "@prisma/client"; @@ -245,7 +245,7 @@ export const createDemoProduct = async (teamId: string) => { // check if updatedEnvironment exists and it has attributeClasses if (!updatedEnvironment || !updatedEnvironment.attributeClasses) { - throw new Error("Attribute classes could not be created"); + throw new ValidationError("Attribute classes could not be created"); } const attributeClasses = updatedEnvironment.attributeClasses; @@ -332,8 +332,12 @@ export const createDemoProduct = async (teamId: string) => { })), }), ]); - } catch (err: any) { - throw new Error(err); + } catch (error: any) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { + throw new DatabaseError("Database operation failed"); + } + + throw error; } // Create a function that creates a survey diff --git a/packages/lib/survey/service.ts b/packages/lib/survey/service.ts index b6d2ff5ed0..df3e4c3ac7 100644 --- a/packages/lib/survey/service.ts +++ b/packages/lib/survey/service.ts @@ -15,7 +15,7 @@ import { revalidateTag, unstable_cache } from "next/cache"; import { z } from "zod"; import { captureTelemetry } from "../telemetry"; import { validateInputs } from "../utils/validate"; -import { getDisplaysCacheTag } from "../services/displays"; +import { getDisplaysCacheTag } from "../display/service"; import { getResponsesCacheTag } from "../response/service"; // surveys cache key and tags diff --git a/packages/surveys/package.json b/packages/surveys/package.json index 2f3b8cc94c..4f8301ae7a 100644 --- a/packages/surveys/package.json +++ b/packages/surveys/package.json @@ -20,7 +20,7 @@ "@preact/preset-vite": "^2.5.0", "autoprefixer": "^10.4.16", "eslint-config-formbricks": "workspace:*", - "postcss": "^8.4.30", + "postcss": "^8.4.31", "preact": "^10.17.1", "tailwindcss": "^3.3.3", "terser": "^5.20.0", diff --git a/packages/tailwind-config/package.json b/packages/tailwind-config/package.json index 0d8a04d8df..73ce4d4d67 100644 --- a/packages/tailwind-config/package.json +++ b/packages/tailwind-config/package.json @@ -10,7 +10,7 @@ "@tailwindcss/forms": "^0.5.6", "@tailwindcss/typography": "^0.5.10", "autoprefixer": "^10.4.16", - "postcss": "^8.4.30", + "postcss": "^8.4.31", "tailwindcss": "^3.3.3" } } diff --git a/packages/types/package.json b/packages/types/package.json index 3a3b260aba..4ca6cd7e68 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -11,6 +11,6 @@ "@formbricks/tsconfig": "workspace:*" }, "dependencies": { - "zod": "^3.22.2" + "zod": "^3.22.3" } } diff --git a/packages/types/v1/errors.ts b/packages/types/v1/errors.ts index e86054c477..1d2e8ee850 100644 --- a/packages/types/v1/errors.ts +++ b/packages/types/v1/errors.ts @@ -22,6 +22,14 @@ class ValidationError extends Error { } } +class UnknownError extends Error { + statusCode = 500; + constructor(message: string) { + super(message); + this.name = "DatabaseError"; + } +} + class DatabaseError extends Error { statusCode = 500; constructor(message: string) { @@ -83,6 +91,7 @@ export { ValidationError, DatabaseError, UniqueConstraintError, + UnknownError, ForeignKeyConstraintError, OperationNotAllowedError, AuthenticationError, diff --git a/packages/ui/package.json b/packages/ui/package.json index 5efb234cdb..fc19e19002 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -16,7 +16,7 @@ "@formbricks/tsconfig": "workspace:*", "concurrently": "^8.2.1", "eslint-config-formbricks": "workspace:*", - "postcss": "^8.4.30", + "postcss": "^8.4.31", "react": "18.2.0" }, "dependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad4dd99137..259452ba58 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -119,7 +119,7 @@ importers: version: 8.10.0 autoprefixer: specifier: ^10.4.15 - version: 10.4.16(postcss@8.4.30) + version: 10.4.16(postcss@8.4.31) clsx: specifier: ^2.0.0 version: 2.0.0 @@ -273,7 +273,7 @@ importers: version: 7.72.0(encoding@0.1.13)(next@13.5.3)(react@18.2.0) '@t3-oss/env-nextjs': specifier: ^0.6.1 - version: 0.6.1(typescript@5.2.2)(zod@3.22.2) + version: 0.6.1(typescript@5.2.2)(zod@3.22.3) bcryptjs: specifier: ^2.4.3 version: 2.4.3 @@ -409,11 +409,11 @@ importers: specifier: ^3.0.1 version: 3.0.1(prisma@5.3.1)(typescript@5.2.2) zod: - specifier: ^3.22.2 - version: 3.22.2 + specifier: ^3.22.3 + version: 3.22.3 zod-prisma: specifier: ^0.5.4 - version: 0.5.4(prisma@5.3.1)(zod@3.22.2) + version: 0.5.4(prisma@5.3.1)(zod@3.22.3) packages/ee: dependencies: @@ -622,13 +622,13 @@ importers: version: 2.5.0(@babel/core@7.23.0)(preact@10.17.1)(vite@4.4.9) autoprefixer: specifier: ^10.4.16 - version: 10.4.16(postcss@8.4.30) + version: 10.4.16(postcss@8.4.31) eslint-config-formbricks: specifier: workspace:* version: link:../eslint-config-formbricks postcss: - specifier: ^8.4.30 - version: 8.4.30 + specifier: ^8.4.31 + version: 8.4.31 preact: specifier: ^10.17.1 version: 10.17.1 @@ -655,10 +655,10 @@ importers: version: 0.5.10(tailwindcss@3.3.3) autoprefixer: specifier: ^10.4.16 - version: 10.4.16(postcss@8.4.30) + version: 10.4.16(postcss@8.4.31) postcss: - specifier: ^8.4.30 - version: 8.4.30 + specifier: ^8.4.31 + version: 8.4.31 tailwindcss: specifier: ^3.3.3 version: 3.3.3 @@ -681,8 +681,8 @@ importers: packages/types: dependencies: zod: - specifier: ^3.22.2 - version: 3.22.2 + specifier: ^3.22.3 + version: 3.22.3 devDependencies: '@formbricks/tsconfig': specifier: workspace:* @@ -794,8 +794,8 @@ importers: specifier: workspace:* version: link:../eslint-config-formbricks postcss: - specifier: ^8.4.30 - version: 8.4.30 + specifier: ^8.4.31 + version: 8.4.31 react: specifier: 18.2.0 version: 18.2.0 @@ -6251,25 +6251,25 @@ packages: dependencies: defer-to-connect: 1.1.3 - /@t3-oss/env-core@0.6.1(typescript@5.2.2)(zod@3.22.2): + /@t3-oss/env-core@0.6.1(typescript@5.2.2)(zod@3.22.3): resolution: {integrity: sha512-KQD7qEDJtkWIWWmTVjNvk0wnHpkvAQ6CRbUxbWMFNG/fiosBQDQvtRpBNu6USxBscJCoC4z6y7P9MN52/mLOzw==} peerDependencies: typescript: '>=4.7.2' zod: ^3.0.0 dependencies: typescript: 5.2.2 - zod: 3.22.2 + zod: 3.22.3 dev: false - /@t3-oss/env-nextjs@0.6.1(typescript@5.2.2)(zod@3.22.2): + /@t3-oss/env-nextjs@0.6.1(typescript@5.2.2)(zod@3.22.3): resolution: {integrity: sha512-z1dIC++Vxj9kmzX5nSPfcrCSkszy3dTEPC4Ssx7Ap5AqR3c2Qa7S0xf8axn6coy7D/vCXDAAnHYnCMDhtcY3SQ==} peerDependencies: typescript: '>=4.7.2' zod: ^3.0.0 dependencies: - '@t3-oss/env-core': 0.6.1(typescript@5.2.2)(zod@3.22.2) + '@t3-oss/env-core': 0.6.1(typescript@5.2.2)(zod@3.22.3) typescript: 5.2.2 - zod: 3.22.2 + zod: 3.22.3 dev: false /@tailwindcss/forms@0.5.6(tailwindcss@3.3.3): @@ -8047,7 +8047,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /autoprefixer@10.4.16(postcss@8.4.30): + /autoprefixer@10.4.16(postcss@8.4.31): resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==} engines: {node: ^10 || ^12 || >=14} hasBin: true @@ -8059,7 +8059,7 @@ packages: fraction.js: 4.3.6 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 /available-typed-arrays@1.0.5: @@ -9896,13 +9896,13 @@ packages: postcss: 8.4.24 dev: true - /css-declaration-sorter@6.3.1(postcss@8.4.30): + /css-declaration-sorter@6.3.1(postcss@8.4.31): resolution: {integrity: sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==} engines: {node: ^10 || ^12 || >=14} peerDependencies: postcss: ^8.0.9 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 dev: true /css-in-js-utils@3.1.0: @@ -9917,13 +9917,13 @@ packages: peerDependencies: webpack: ^4.27.0 || ^5.0.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.30) + icss-utils: 5.1.0(postcss@8.4.31) loader-utils: 2.0.4 - postcss: 8.4.30 - postcss-modules-extract-imports: 3.0.0(postcss@8.4.30) - postcss-modules-local-by-default: 4.0.0(postcss@8.4.30) - postcss-modules-scope: 3.0.0(postcss@8.4.30) - postcss-modules-values: 4.0.0(postcss@8.4.30) + postcss: 8.4.31 + postcss-modules-extract-imports: 3.0.0(postcss@8.4.31) + postcss-modules-local-by-default: 4.0.0(postcss@8.4.31) + postcss-modules-scope: 3.0.0(postcss@8.4.31) + postcss-modules-values: 4.0.0(postcss@8.4.31) postcss-value-parser: 4.2.0 schema-utils: 3.1.1 semver: 7.5.4 @@ -10066,42 +10066,42 @@ packages: postcss-unique-selectors: 5.1.1(postcss@8.4.24) dev: true - /cssnano-preset-default@5.2.13(postcss@8.4.30): + /cssnano-preset-default@5.2.13(postcss@8.4.31): resolution: {integrity: sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - css-declaration-sorter: 6.3.1(postcss@8.4.30) - cssnano-utils: 3.1.0(postcss@8.4.30) - postcss: 8.4.30 - postcss-calc: 8.2.4(postcss@8.4.30) - postcss-colormin: 5.3.0(postcss@8.4.30) - postcss-convert-values: 5.1.3(postcss@8.4.30) - postcss-discard-comments: 5.1.2(postcss@8.4.30) - postcss-discard-duplicates: 5.1.0(postcss@8.4.30) - postcss-discard-empty: 5.1.1(postcss@8.4.30) - postcss-discard-overridden: 5.1.0(postcss@8.4.30) - postcss-merge-longhand: 5.1.7(postcss@8.4.30) - postcss-merge-rules: 5.1.3(postcss@8.4.30) - postcss-minify-font-values: 5.1.0(postcss@8.4.30) - postcss-minify-gradients: 5.1.1(postcss@8.4.30) - postcss-minify-params: 5.1.4(postcss@8.4.30) - postcss-minify-selectors: 5.2.1(postcss@8.4.30) - postcss-normalize-charset: 5.1.0(postcss@8.4.30) - postcss-normalize-display-values: 5.1.0(postcss@8.4.30) - postcss-normalize-positions: 5.1.1(postcss@8.4.30) - postcss-normalize-repeat-style: 5.1.1(postcss@8.4.30) - postcss-normalize-string: 5.1.0(postcss@8.4.30) - postcss-normalize-timing-functions: 5.1.0(postcss@8.4.30) - postcss-normalize-unicode: 5.1.1(postcss@8.4.30) - postcss-normalize-url: 5.1.0(postcss@8.4.30) - postcss-normalize-whitespace: 5.1.1(postcss@8.4.30) - postcss-ordered-values: 5.1.3(postcss@8.4.30) - postcss-reduce-initial: 5.1.1(postcss@8.4.30) - postcss-reduce-transforms: 5.1.0(postcss@8.4.30) - postcss-svgo: 5.1.0(postcss@8.4.30) - postcss-unique-selectors: 5.1.1(postcss@8.4.30) + css-declaration-sorter: 6.3.1(postcss@8.4.31) + cssnano-utils: 3.1.0(postcss@8.4.31) + postcss: 8.4.31 + postcss-calc: 8.2.4(postcss@8.4.31) + postcss-colormin: 5.3.0(postcss@8.4.31) + postcss-convert-values: 5.1.3(postcss@8.4.31) + postcss-discard-comments: 5.1.2(postcss@8.4.31) + postcss-discard-duplicates: 5.1.0(postcss@8.4.31) + postcss-discard-empty: 5.1.1(postcss@8.4.31) + postcss-discard-overridden: 5.1.0(postcss@8.4.31) + postcss-merge-longhand: 5.1.7(postcss@8.4.31) + postcss-merge-rules: 5.1.3(postcss@8.4.31) + postcss-minify-font-values: 5.1.0(postcss@8.4.31) + postcss-minify-gradients: 5.1.1(postcss@8.4.31) + postcss-minify-params: 5.1.4(postcss@8.4.31) + postcss-minify-selectors: 5.2.1(postcss@8.4.31) + postcss-normalize-charset: 5.1.0(postcss@8.4.31) + postcss-normalize-display-values: 5.1.0(postcss@8.4.31) + postcss-normalize-positions: 5.1.1(postcss@8.4.31) + postcss-normalize-repeat-style: 5.1.1(postcss@8.4.31) + postcss-normalize-string: 5.1.0(postcss@8.4.31) + postcss-normalize-timing-functions: 5.1.0(postcss@8.4.31) + postcss-normalize-unicode: 5.1.1(postcss@8.4.31) + postcss-normalize-url: 5.1.0(postcss@8.4.31) + postcss-normalize-whitespace: 5.1.1(postcss@8.4.31) + postcss-ordered-values: 5.1.3(postcss@8.4.31) + postcss-reduce-initial: 5.1.1(postcss@8.4.31) + postcss-reduce-transforms: 5.1.0(postcss@8.4.31) + postcss-svgo: 5.1.0(postcss@8.4.31) + postcss-unique-selectors: 5.1.1(postcss@8.4.31) dev: true /cssnano-util-get-arguments@4.0.0: @@ -10135,13 +10135,13 @@ packages: postcss: 8.4.24 dev: true - /cssnano-utils@3.1.0(postcss@8.4.30): + /cssnano-utils@3.1.0(postcss@8.4.31): resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 dev: true /cssnano@4.1.11: @@ -10166,15 +10166,15 @@ packages: yaml: 1.10.2 dev: true - /cssnano@5.1.14(postcss@8.4.30): + /cssnano@5.1.14(postcss@8.4.31): resolution: {integrity: sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - cssnano-preset-default: 5.2.13(postcss@8.4.30) + cssnano-preset-default: 5.2.13(postcss@8.4.31) lilconfig: 2.1.0 - postcss: 8.4.30 + postcss: 8.4.31 yaml: 1.10.2 dev: true @@ -13747,13 +13747,13 @@ packages: postcss: 8.4.24 dev: true - /icss-utils@5.1.0(postcss@8.4.30): + /icss-utils@5.1.0(postcss@8.4.31): resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 dev: true /idb@7.1.1: @@ -17827,9 +17827,9 @@ packages: peerDependencies: webpack: ^4.0.0 dependencies: - cssnano: 5.1.14(postcss@8.4.30) + cssnano: 5.1.14(postcss@8.4.31) last-call-webpack-plugin: 3.0.0 - postcss: 8.4.30 + postcss: 8.4.31 webpack: 4.46.0 dev: true @@ -18400,12 +18400,12 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-calc@8.2.4(postcss@8.4.30): + /postcss-calc@8.2.4(postcss@8.4.31): resolution: {integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==} peerDependencies: postcss: ^8.2.2 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-selector-parser: 6.0.11 postcss-value-parser: 4.2.0 dev: true @@ -18434,7 +18434,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-colormin@5.3.0(postcss@8.4.30): + /postcss-colormin@5.3.0(postcss@8.4.31): resolution: {integrity: sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: @@ -18443,7 +18443,7 @@ packages: browserslist: 4.21.10 caniuse-api: 3.0.0 colord: 2.9.3 - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -18466,14 +18466,14 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-convert-values@5.1.3(postcss@8.4.30): + /postcss-convert-values@5.1.3(postcss@8.4.31): resolution: {integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: browserslist: 4.21.10 - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -18504,13 +18504,13 @@ packages: postcss: 8.4.24 dev: true - /postcss-discard-comments@5.1.2(postcss@8.4.30): + /postcss-discard-comments@5.1.2(postcss@8.4.31): resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 dev: true /postcss-discard-duplicates@4.0.2: @@ -18529,13 +18529,13 @@ packages: postcss: 8.4.24 dev: true - /postcss-discard-duplicates@5.1.0(postcss@8.4.30): + /postcss-discard-duplicates@5.1.0(postcss@8.4.31): resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 dev: true /postcss-discard-empty@4.0.1: @@ -18554,13 +18554,13 @@ packages: postcss: 8.4.24 dev: true - /postcss-discard-empty@5.1.1(postcss@8.4.30): + /postcss-discard-empty@5.1.1(postcss@8.4.31): resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 dev: true /postcss-discard-overridden@4.0.1: @@ -18579,13 +18579,13 @@ packages: postcss: 8.4.24 dev: true - /postcss-discard-overridden@5.1.0(postcss@8.4.30): + /postcss-discard-overridden@5.1.0(postcss@8.4.31): resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 dev: true /postcss-import@14.1.0(postcss@8.4.21): @@ -18697,6 +18697,23 @@ packages: postcss: 8.4.27 yaml: 2.3.1 + /postcss-load-config@4.0.1(postcss@8.4.31): + resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.1.0 + postcss: 8.4.31 + yaml: 2.3.1 + dev: true + /postcss-loader@4.3.0(postcss@8.4.27)(webpack@4.46.0): resolution: {integrity: sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q==} engines: {node: '>= 10.13.0'} @@ -18734,15 +18751,15 @@ packages: stylehacks: 5.1.1(postcss@8.4.24) dev: true - /postcss-merge-longhand@5.1.7(postcss@8.4.30): + /postcss-merge-longhand@5.1.7(postcss@8.4.31): resolution: {integrity: sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 - stylehacks: 5.1.1(postcss@8.4.30) + stylehacks: 5.1.1(postcss@8.4.31) dev: true /postcss-merge-rules@4.0.3: @@ -18770,7 +18787,7 @@ packages: postcss-selector-parser: 6.0.11 dev: true - /postcss-merge-rules@5.1.3(postcss@8.4.30): + /postcss-merge-rules@5.1.3(postcss@8.4.31): resolution: {integrity: sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: @@ -18778,8 +18795,8 @@ packages: dependencies: browserslist: 4.21.10 caniuse-api: 3.0.0 - cssnano-utils: 3.1.0(postcss@8.4.30) - postcss: 8.4.30 + cssnano-utils: 3.1.0(postcss@8.4.31) + postcss: 8.4.31 postcss-selector-parser: 6.0.11 dev: true @@ -18801,13 +18818,13 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-minify-font-values@5.1.0(postcss@8.4.30): + /postcss-minify-font-values@5.1.0(postcss@8.4.31): resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -18833,15 +18850,15 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-minify-gradients@5.1.1(postcss@8.4.30): + /postcss-minify-gradients@5.1.1(postcss@8.4.31): resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: colord: 2.9.3 - cssnano-utils: 3.1.0(postcss@8.4.30) - postcss: 8.4.30 + cssnano-utils: 3.1.0(postcss@8.4.31) + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -18869,15 +18886,15 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-minify-params@5.1.4(postcss@8.4.30): + /postcss-minify-params@5.1.4(postcss@8.4.31): resolution: {integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: browserslist: 4.21.10 - cssnano-utils: 3.1.0(postcss@8.4.30) - postcss: 8.4.30 + cssnano-utils: 3.1.0(postcss@8.4.31) + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -18901,13 +18918,13 @@ packages: postcss-selector-parser: 6.0.11 dev: true - /postcss-minify-selectors@5.2.1(postcss@8.4.30): + /postcss-minify-selectors@5.2.1(postcss@8.4.31): resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-selector-parser: 6.0.11 dev: true @@ -18920,13 +18937,13 @@ packages: postcss: 8.4.24 dev: true - /postcss-modules-extract-imports@3.0.0(postcss@8.4.30): + /postcss-modules-extract-imports@3.0.0(postcss@8.4.31): resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 dev: true /postcss-modules-local-by-default@4.0.0(postcss@8.4.24): @@ -18941,14 +18958,14 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-modules-local-by-default@4.0.0(postcss@8.4.30): + /postcss-modules-local-by-default@4.0.0(postcss@8.4.31): resolution: {integrity: sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.30) - postcss: 8.4.30 + icss-utils: 5.1.0(postcss@8.4.31) + postcss: 8.4.31 postcss-selector-parser: 6.0.11 postcss-value-parser: 4.2.0 dev: true @@ -18963,13 +18980,13 @@ packages: postcss-selector-parser: 6.0.11 dev: true - /postcss-modules-scope@3.0.0(postcss@8.4.30): + /postcss-modules-scope@3.0.0(postcss@8.4.31): resolution: {integrity: sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-selector-parser: 6.0.11 dev: true @@ -18983,14 +19000,14 @@ packages: postcss: 8.4.24 dev: true - /postcss-modules-values@4.0.0(postcss@8.4.30): + /postcss-modules-values@4.0.0(postcss@8.4.31): resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.30) - postcss: 8.4.30 + icss-utils: 5.1.0(postcss@8.4.31) + postcss: 8.4.31 dev: true /postcss-modules@4.3.1(postcss@8.4.24): @@ -19044,13 +19061,13 @@ packages: postcss: 8.4.24 dev: true - /postcss-normalize-charset@5.1.0(postcss@8.4.30): + /postcss-normalize-charset@5.1.0(postcss@8.4.31): resolution: {integrity: sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 dev: true /postcss-normalize-display-values@4.0.2: @@ -19072,13 +19089,13 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-display-values@5.1.0(postcss@8.4.30): + /postcss-normalize-display-values@5.1.0(postcss@8.4.31): resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -19102,13 +19119,13 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-positions@5.1.1(postcss@8.4.30): + /postcss-normalize-positions@5.1.1(postcss@8.4.31): resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -19132,13 +19149,13 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-repeat-style@5.1.1(postcss@8.4.30): + /postcss-normalize-repeat-style@5.1.1(postcss@8.4.31): resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -19161,13 +19178,13 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-string@5.1.0(postcss@8.4.30): + /postcss-normalize-string@5.1.0(postcss@8.4.31): resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -19190,13 +19207,13 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-timing-functions@5.1.0(postcss@8.4.30): + /postcss-normalize-timing-functions@5.1.0(postcss@8.4.31): resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -19220,14 +19237,14 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-unicode@5.1.1(postcss@8.4.30): + /postcss-normalize-unicode@5.1.1(postcss@8.4.31): resolution: {integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: browserslist: 4.21.10 - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -19252,14 +19269,14 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-url@5.1.0(postcss@8.4.30): + /postcss-normalize-url@5.1.0(postcss@8.4.31): resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: normalize-url: 6.1.0 - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -19281,13 +19298,13 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-whitespace@5.1.1(postcss@8.4.30): + /postcss-normalize-whitespace@5.1.1(postcss@8.4.31): resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -19311,14 +19328,14 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-ordered-values@5.1.3(postcss@8.4.30): + /postcss-ordered-values@5.1.3(postcss@8.4.31): resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - cssnano-utils: 3.1.0(postcss@8.4.30) - postcss: 8.4.30 + cssnano-utils: 3.1.0(postcss@8.4.31) + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -19343,7 +19360,7 @@ packages: postcss: 8.4.24 dev: true - /postcss-reduce-initial@5.1.1(postcss@8.4.30): + /postcss-reduce-initial@5.1.1(postcss@8.4.31): resolution: {integrity: sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: @@ -19351,7 +19368,7 @@ packages: dependencies: browserslist: 4.21.10 caniuse-api: 3.0.0 - postcss: 8.4.30 + postcss: 8.4.31 dev: true /postcss-reduce-transforms@4.0.2: @@ -19374,13 +19391,13 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-reduce-transforms@5.1.0(postcss@8.4.30): + /postcss-reduce-transforms@5.1.0(postcss@8.4.31): resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -19427,13 +19444,13 @@ packages: svgo: 2.8.0 dev: true - /postcss-svgo@5.1.0(postcss@8.4.30): + /postcss-svgo@5.1.0(postcss@8.4.31): resolution: {integrity: sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-value-parser: 4.2.0 svgo: 2.8.0 dev: true @@ -19457,13 +19474,13 @@ packages: postcss-selector-parser: 6.0.11 dev: true - /postcss-unique-selectors@5.1.1(postcss@8.4.30): + /postcss-unique-selectors@5.1.1(postcss@8.4.31): resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: - postcss: 8.4.30 + postcss: 8.4.31 postcss-selector-parser: 6.0.11 dev: true @@ -19517,8 +19534,8 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 - /postcss@8.4.30: - resolution: {integrity: sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==} + /postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.6 @@ -22394,14 +22411,14 @@ packages: postcss-selector-parser: 6.0.11 dev: true - /stylehacks@5.1.1(postcss@8.4.30): + /stylehacks@5.1.1(postcss@8.4.31): resolution: {integrity: sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 dependencies: browserslist: 4.21.10 - postcss: 8.4.30 + postcss: 8.4.31 postcss-selector-parser: 6.0.11 dev: true @@ -23141,7 +23158,7 @@ packages: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 4.0.1(postcss@8.4.27) + postcss-load-config: 4.0.1(postcss@8.4.31) resolve-from: 5.0.0 rollup: 3.5.1 source-map: 0.8.0-beta.0 @@ -24154,7 +24171,7 @@ packages: optional: true dependencies: esbuild: 0.18.10 - postcss: 8.4.30 + postcss: 8.4.31 rollup: 3.28.1 terser: 5.20.0 optionalDependencies: @@ -25121,7 +25138,7 @@ packages: readable-stream: 3.6.0 dev: true - /zod-prisma@0.5.4(prisma@5.3.1)(zod@3.22.2): + /zod-prisma@0.5.4(prisma@5.3.1)(zod@3.22.3): resolution: {integrity: sha512-5Ca4Qd1a1jy1T/NqCEpbr0c+EsbjJfJ/7euEHob3zDvtUK2rTuD1Rc/vfzH8q8PtaR2TZbysD88NHmrLwpv3Xg==} engines: {node: '>=14'} hasBin: true @@ -25137,15 +25154,15 @@ packages: parenthesis: 3.1.8 prisma: 5.3.1 ts-morph: 13.0.3 - zod: 3.22.2 + zod: 3.22.3 dev: true /zod@3.21.4: resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==} dev: false - /zod@3.22.2: - resolution: {integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==} + /zod@3.22.3: + resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} /zustand@4.4.1(@types/react@18.2.23)(react@18.2.0): resolution: {integrity: sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw==}