mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-09 21:14:22 +00:00
feat: upgrade to React 19, Next.js 15, React Compiler, HeroUI and Tailwind 4 (#8748)
Co-authored-by: Alan Buscaglia <alanbuscaglia@MacBook-Pro.local> Co-authored-by: alejandrobailo <alejandrobailo94@gmail.com> Co-authored-by: César Arroba <cesar@prowler.com> Co-authored-by: Alejandro Bailo <59607668+alejandrobailo@users.noreply.github.com>
This commit is contained in:
co-authored by
Alan Buscaglia
alejandrobailo
César Arroba
Alejandro Bailo
parent
2a4b62527a
commit
4d5676f00e
@@ -69,7 +69,7 @@ export interface ComplianceMapper {
|
||||
getDetailsComponent: (requirement: Requirement) => React.ReactNode;
|
||||
}
|
||||
|
||||
const defaultMapper: ComplianceMapper = {
|
||||
const getDefaultMapper = (): ComplianceMapper => ({
|
||||
mapComplianceData: mapGenericComplianceData,
|
||||
toAccordionItems: toGenericAccordionItems,
|
||||
getTopFailedSections,
|
||||
@@ -77,22 +77,9 @@ const defaultMapper: ComplianceMapper = {
|
||||
calculateCategoryHeatmapData(data),
|
||||
getDetailsComponent: (requirement: Requirement) =>
|
||||
React.createElement(GenericCustomDetails, { requirement }),
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Get the appropriate compliance mapper based on the framework name
|
||||
* @param framework - The framework name (e.g., "ENS", "ISO27001", "CIS")
|
||||
* @returns ComplianceMapper object with specific functions for the framework
|
||||
*/
|
||||
export const getComplianceMapper = (framework?: string): ComplianceMapper => {
|
||||
if (!framework) {
|
||||
return defaultMapper;
|
||||
}
|
||||
|
||||
return complianceMappers[framework] || defaultMapper;
|
||||
};
|
||||
|
||||
export const complianceMappers: Record<string, ComplianceMapper> = {
|
||||
const getComplianceMappers = (): Record<string, ComplianceMapper> => ({
|
||||
ENS: {
|
||||
mapComplianceData: mapENSComplianceData,
|
||||
toAccordionItems: toENSAccordionItems,
|
||||
@@ -164,4 +151,18 @@ export const complianceMappers: Record<string, ComplianceMapper> = {
|
||||
getDetailsComponent: (requirement: Requirement) =>
|
||||
React.createElement(ThreatCustomDetails, { requirement }),
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Get the appropriate compliance mapper based on the framework name
|
||||
* @param framework - The framework name (e.g., "ENS", "ISO27001", "CIS")
|
||||
* @returns ComplianceMapper object with specific functions for the framework
|
||||
*/
|
||||
export const getComplianceMapper = (framework?: string): ComplianceMapper => {
|
||||
if (!framework) {
|
||||
return getDefaultMapper();
|
||||
}
|
||||
|
||||
const complianceMappers = getComplianceMappers();
|
||||
return complianceMappers[framework] || getDefaultMapper();
|
||||
};
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
import { getComplianceCsv, getExportsZip } from "@/actions/scans";
|
||||
import { getTask } from "@/actions/task";
|
||||
import { auth } from "@/auth.config";
|
||||
@@ -340,85 +338,3 @@ export const permissionFormFields: PermissionInfo[] = [
|
||||
description: "Provides access to billing settings and invoices",
|
||||
},
|
||||
];
|
||||
|
||||
// Helper function to handle API responses consistently
|
||||
export const handleApiResponse = async (
|
||||
response: Response,
|
||||
pathToRevalidate?: string,
|
||||
parse = true,
|
||||
) => {
|
||||
if (!response.ok) {
|
||||
// Read error body safely; prefer JSON, fallback to plain text
|
||||
const rawErrorText = await response.text().catch(() => "");
|
||||
let errorData: any = null;
|
||||
try {
|
||||
errorData = rawErrorText ? JSON.parse(rawErrorText) : null;
|
||||
} catch {
|
||||
errorData = null;
|
||||
}
|
||||
|
||||
const errorsArray = Array.isArray(errorData?.errors)
|
||||
? (errorData.errors as any[])
|
||||
: undefined;
|
||||
const errorDetail =
|
||||
errorsArray?.[0]?.detail ||
|
||||
errorData?.error ||
|
||||
errorData?.message ||
|
||||
(rawErrorText && rawErrorText.trim()) ||
|
||||
response.statusText ||
|
||||
"Oops! Something went wrong.";
|
||||
|
||||
//5XX errors
|
||||
if (response.status >= 500) {
|
||||
throw new Error(
|
||||
errorDetail ||
|
||||
`Server error (${response.status}): The server encountered an error. Please try again later.`,
|
||||
);
|
||||
}
|
||||
|
||||
return errorsArray
|
||||
? { error: errorDetail, errors: errorsArray, status: response.status }
|
||||
: ({ error: errorDetail, status: response.status } as any);
|
||||
}
|
||||
|
||||
// Handle empty or no-content responses gracefully (e.g., 204, empty body)
|
||||
if (response.status === 204) {
|
||||
if (pathToRevalidate && pathToRevalidate !== "") {
|
||||
revalidatePath(pathToRevalidate);
|
||||
}
|
||||
return { success: true, status: response.status } as any;
|
||||
}
|
||||
|
||||
// Read raw text to determine if there's a body to parse
|
||||
const rawText = await response.text();
|
||||
const hasBody = rawText && rawText.trim().length > 0;
|
||||
|
||||
if (!hasBody) {
|
||||
if (pathToRevalidate && pathToRevalidate !== "") {
|
||||
revalidatePath(pathToRevalidate);
|
||||
}
|
||||
return { success: true, status: response.status } as any;
|
||||
}
|
||||
|
||||
let data: any;
|
||||
try {
|
||||
data = JSON.parse(rawText);
|
||||
} catch (e) {
|
||||
// If body isn't valid JSON, return as text payload
|
||||
data = { data: rawText };
|
||||
}
|
||||
|
||||
if (pathToRevalidate && pathToRevalidate !== "") {
|
||||
revalidatePath(pathToRevalidate);
|
||||
}
|
||||
|
||||
return parse ? parseStringify(data) : data;
|
||||
};
|
||||
|
||||
// Helper function to handle API errors consistently
|
||||
export const handleApiError = (error: unknown): { error: string } => {
|
||||
console.error(error);
|
||||
return {
|
||||
error: getErrorMessage(error),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -35,7 +35,7 @@ export const convertVercelMessageToLangChainMessage = (
|
||||
export const convertLangChainMessageToVercelMessage = (
|
||||
message: BaseMessage,
|
||||
) => {
|
||||
switch (message.getType()) {
|
||||
switch (message._getType()) {
|
||||
case "human":
|
||||
return { content: message.content, role: "user" };
|
||||
case "ai":
|
||||
@@ -45,7 +45,7 @@ export const convertLangChainMessageToVercelMessage = (
|
||||
tool_calls: (message as AIMessage).tool_calls,
|
||||
};
|
||||
default:
|
||||
return { content: message.content, role: message.getType() };
|
||||
return { content: message.content, role: message._getType() };
|
||||
}
|
||||
};
|
||||
|
||||
@@ -60,7 +60,7 @@ export const getModelParams = (config: any): ModelParams => {
|
||||
|
||||
if (modelId.startsWith("gpt-5")) {
|
||||
params.temperature = undefined;
|
||||
params.reasoningEffort = "minimal";
|
||||
params.reasoningEffort = "minimal" as const;
|
||||
}
|
||||
|
||||
return params;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Bookmark,
|
||||
CloudCog,
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
import { getErrorMessage, parseStringify } from "./helper";
|
||||
|
||||
// Helper function to handle API responses consistently
|
||||
export const handleApiResponse = async (
|
||||
response: Response,
|
||||
pathToRevalidate?: string,
|
||||
parse = true,
|
||||
) => {
|
||||
if (!response.ok) {
|
||||
// Read error body safely; prefer JSON, fallback to plain text
|
||||
const rawErrorText = await response.text().catch(() => "");
|
||||
let errorData: any = null;
|
||||
try {
|
||||
errorData = rawErrorText ? JSON.parse(rawErrorText) : null;
|
||||
} catch {
|
||||
errorData = null;
|
||||
}
|
||||
|
||||
const errorsArray = Array.isArray(errorData?.errors)
|
||||
? (errorData.errors as any[])
|
||||
: undefined;
|
||||
const errorDetail =
|
||||
errorsArray?.[0]?.detail ||
|
||||
errorData?.error ||
|
||||
errorData?.message ||
|
||||
(rawErrorText && rawErrorText.trim()) ||
|
||||
response.statusText ||
|
||||
"Oops! Something went wrong.";
|
||||
|
||||
//5XX errors
|
||||
if (response.status >= 500) {
|
||||
throw new Error(
|
||||
errorDetail ||
|
||||
`Server error (${response.status}): The server encountered an error. Please try again later.`,
|
||||
);
|
||||
}
|
||||
|
||||
return errorsArray
|
||||
? { error: errorDetail, errors: errorsArray, status: response.status }
|
||||
: ({ error: errorDetail, status: response.status } as any);
|
||||
}
|
||||
|
||||
// Handle empty or no-content responses gracefully (e.g., 204, empty body)
|
||||
if (response.status === 204) {
|
||||
if (pathToRevalidate && pathToRevalidate !== "") {
|
||||
revalidatePath(pathToRevalidate);
|
||||
}
|
||||
return { success: true, status: response.status } as any;
|
||||
}
|
||||
|
||||
// Read raw text to determine if there's a body to parse
|
||||
const rawText = await response.text();
|
||||
const hasBody = rawText && rawText.trim().length > 0;
|
||||
|
||||
if (!hasBody) {
|
||||
if (pathToRevalidate && pathToRevalidate !== "") {
|
||||
revalidatePath(pathToRevalidate);
|
||||
}
|
||||
return { success: true, status: response.status } as any;
|
||||
}
|
||||
|
||||
let data: any;
|
||||
try {
|
||||
data = JSON.parse(rawText);
|
||||
} catch (e) {
|
||||
// If body isn't valid JSON, return as text payload
|
||||
data = { data: rawText };
|
||||
}
|
||||
|
||||
if (pathToRevalidate && pathToRevalidate !== "") {
|
||||
revalidatePath(pathToRevalidate);
|
||||
}
|
||||
|
||||
return parse ? parseStringify(data) : data;
|
||||
};
|
||||
|
||||
// Helper function to handle API errors consistently
|
||||
export const handleApiError = (error: unknown): { error: string } => {
|
||||
console.error(error);
|
||||
return {
|
||||
error: getErrorMessage(error),
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user