diff --git a/containers/ecr-viewer/jest.setup.ts b/containers/ecr-viewer/jest.setup.ts index 5c63e99fe..419692661 100644 --- a/containers/ecr-viewer/jest.setup.ts +++ b/containers/ecr-viewer/jest.setup.ts @@ -2,8 +2,22 @@ import "@testing-library/jest-dom"; import { toHaveNoViolations } from "jest-axe"; import * as matchers from "jest-extended"; import { TextEncoder } from "util"; +import router from "next-router-mock"; global.TextEncoder = TextEncoder; expect.extend(toHaveNoViolations); expect.extend(matchers); + +// Mocking `next/navigation` hooks +jest.mock("next/navigation", () => ({ + useRouter: () => router, + usePathname: () => router.pathname, + useSearchParams: () => { + const params = new URLSearchParams(router.asPath.split("?")[1]); + return { + get: params.get.bind(params), + toString: () => params.toString(), + }; + }, +})); diff --git a/containers/ecr-viewer/package.json b/containers/ecr-viewer/package.json index bf5226163..ee8b429f5 100644 --- a/containers/ecr-viewer/package.json +++ b/containers/ecr-viewer/package.json @@ -56,6 +56,7 @@ "mssql": "^11.0.1", "next": "^14.2.14", "next-auth": "^4.24.7", + "next-router-mock": "^0.9.13", "pg-promise": "^11.6.0", "react": "^18", "react-dom": "^18", diff --git a/containers/ecr-viewer/src/app/api/services/listEcrDataService.ts b/containers/ecr-viewer/src/app/api/services/listEcrDataService.ts index 7fdcf14fc..d4f6b5270 100644 --- a/containers/ecr-viewer/src/app/api/services/listEcrDataService.ts +++ b/containers/ecr-viewer/src/app/api/services/listEcrDataService.ts @@ -33,20 +33,25 @@ export type EcrDisplay = { /** * @param startIndex - The index of the first item to fetch * @param itemsPerPage - The number of items to fetch + * @param sortColumn - The column to sort by + * @param sortDirection - The direction to sort by * @param searchTerm - The search term to use * @returns A promise resolving to a list of eCR metadata */ export async function listEcrData( startIndex: number, itemsPerPage: number, + sortColumn: string, + sortDirection: string, searchTerm?: string, ): Promise { const list = await database.manyOrNone( - "SELECT ed.eICR_ID, ed.patient_name_first, ed.patient_name_last, ed.patient_birth_date, ed.date_created, ed.report_date, erc.condition, ers.rule_summary, ed.report_date FROM ecr_data ed LEFT JOIN ecr_rr_conditions erc ON ed.eICR_ID = erc.eICR_ID LEFT JOIN ecr_rr_rule_summaries ers ON erc.uuid = ers.ecr_rr_conditions_id where $[whereClause] order by ed.report_date DESC OFFSET $[startIndex] ROWS FETCH NEXT $[itemsPerPage] ROWS ONLY", + "SELECT ed.eICR_ID, ed.patient_name_first, ed.patient_name_last, ed.patient_birth_date, ed.date_created, ed.report_date, erc.condition, ers.rule_summary, ed.report_date FROM ecr_data ed LEFT JOIN ecr_rr_conditions erc ON ed.eICR_ID = erc.eICR_ID LEFT JOIN ecr_rr_rule_summaries ers ON erc.uuid = ers.ecr_rr_conditions_id where $[whereClause] $[sortStatement] OFFSET $[startIndex] ROWS FETCH NEXT $[itemsPerPage] ROWS ONLY", { whereClause: generateSearchStatement(searchTerm), startIndex, itemsPerPage, + sortStatement: generateSortStatement(sortColumn, sortDirection), }, ); return processMetadata(list); @@ -121,3 +126,41 @@ export const generateSearchStatement = (searchTerm?: string) => ({ .join(" OR "); }, }); + +/** + * A custom type format for sort statement + * @param columnName - The column to sort by + * @param direction - The direction to sort by + * @returns custom type format object for use by pg-promise + */ +export const generateSortStatement = ( + columnName: string, + direction: string, +) => ({ + rawType: true, + toPostgres: () => { + // Valid columns and directions + const validColumns = ["patient", "date_created", "report_date"]; + const validDirections = ["ASC", "DESC"]; + + // Validation check + if (!validColumns.includes(columnName)) { + columnName = "date_created"; + } + if (!validDirections.includes(direction)) { + direction = "DESC"; + } + + if (columnName === "patient") { + return pgPromise.as.format( + `ORDER BY ed.patient_name_last ${direction}, ed.patient_name_first ${direction}`, + { direction }, + ); + } + + // Default case for other columns + return pgPromise.as.format(`ORDER BY $[columnName:raw] ${direction}`, { + columnName, + }); + }, +}); diff --git a/containers/ecr-viewer/src/app/api/tests/listEcrDataService.test.tsx b/containers/ecr-viewer/src/app/api/tests/listEcrDataService.test.tsx index ca8e7601d..7d51eb690 100644 --- a/containers/ecr-viewer/src/app/api/tests/listEcrDataService.test.tsx +++ b/containers/ecr-viewer/src/app/api/tests/listEcrDataService.test.tsx @@ -102,15 +102,23 @@ describe("listEcrDataService", () => { it("should return empty array when no data is found", async () => { let startIndex = 0; let itemsPerPage = 25; + let columnName = "date_created"; + let direction = "DESC"; database.manyOrNone = jest.fn(() => Promise.resolve([])); - const actual = await listEcrData(startIndex, itemsPerPage); + const actual = await listEcrData( + startIndex, + itemsPerPage, + columnName, + direction, + ); expect(database.manyOrNone).toHaveBeenCalledOnce(); expect(database.manyOrNone).toHaveBeenCalledWith( - "SELECT ed.eICR_ID, ed.patient_name_first, ed.patient_name_last, ed.patient_birth_date, ed.date_created, ed.report_date, erc.condition, ers.rule_summary, ed.report_date FROM ecr_data ed LEFT JOIN ecr_rr_conditions erc ON ed.eICR_ID = erc.eICR_ID LEFT JOIN ecr_rr_rule_summaries ers ON erc.uuid = ers.ecr_rr_conditions_id where $[whereClause] order by ed.report_date DESC OFFSET $[startIndex] ROWS FETCH NEXT $[itemsPerPage] ROWS ONLY", + "SELECT ed.eICR_ID, ed.patient_name_first, ed.patient_name_last, ed.patient_birth_date, ed.date_created, ed.report_date, erc.condition, ers.rule_summary, ed.report_date FROM ecr_data ed LEFT JOIN ecr_rr_conditions erc ON ed.eICR_ID = erc.eICR_ID LEFT JOIN ecr_rr_rule_summaries ers ON erc.uuid = ers.ecr_rr_conditions_id where $[whereClause] $[sortStatement] OFFSET $[startIndex] ROWS FETCH NEXT $[itemsPerPage] ROWS ONLY", { whereClause: expect.any(Object), startIndex, itemsPerPage, + sortStatement: expect.any(Object), }, ); expect(actual).toBeEmpty(); @@ -137,15 +145,23 @@ describe("listEcrDataService", () => { let startIndex = 0; let itemsPerPage = 25; - const actual: EcrDisplay[] = await listEcrData(startIndex, itemsPerPage); + let columnName = "date_created"; + let direction = "DESC"; + const actual: EcrDisplay[] = await listEcrData( + startIndex, + itemsPerPage, + columnName, + direction, + ); expect(database.manyOrNone).toHaveBeenCalledOnce(); expect(database.manyOrNone).toHaveBeenCalledWith( - "SELECT ed.eICR_ID, ed.patient_name_first, ed.patient_name_last, ed.patient_birth_date, ed.date_created, ed.report_date, erc.condition, ers.rule_summary, ed.report_date FROM ecr_data ed LEFT JOIN ecr_rr_conditions erc ON ed.eICR_ID = erc.eICR_ID LEFT JOIN ecr_rr_rule_summaries ers ON erc.uuid = ers.ecr_rr_conditions_id where $[whereClause] order by ed.report_date DESC OFFSET $[startIndex] ROWS FETCH NEXT $[itemsPerPage] ROWS ONLY", + "SELECT ed.eICR_ID, ed.patient_name_first, ed.patient_name_last, ed.patient_birth_date, ed.date_created, ed.report_date, erc.condition, ers.rule_summary, ed.report_date FROM ecr_data ed LEFT JOIN ecr_rr_conditions erc ON ed.eICR_ID = erc.eICR_ID LEFT JOIN ecr_rr_rule_summaries ers ON erc.uuid = ers.ecr_rr_conditions_id where $[whereClause] $[sortStatement] OFFSET $[startIndex] ROWS FETCH NEXT $[itemsPerPage] ROWS ONLY", { whereClause: expect.any(Object), startIndex, itemsPerPage, + sortStatement: expect.any(Object), }, ); expect(actual).toEqual([ @@ -183,14 +199,22 @@ describe("listEcrDataService", () => { let startIndex = 0; let itemsPerPage = 25; - const actual: EcrDisplay[] = await listEcrData(startIndex, itemsPerPage); + let columnName = "date_created"; + let direction = "DESC"; + const actual: EcrDisplay[] = await listEcrData( + startIndex, + itemsPerPage, + columnName, + direction, + ); expect(database.manyOrNone).toHaveBeenCalledOnce(); expect(database.manyOrNone).toHaveBeenCalledWith( - "SELECT ed.eICR_ID, ed.patient_name_first, ed.patient_name_last, ed.patient_birth_date, ed.date_created, ed.report_date, erc.condition, ers.rule_summary, ed.report_date FROM ecr_data ed LEFT JOIN ecr_rr_conditions erc ON ed.eICR_ID = erc.eICR_ID LEFT JOIN ecr_rr_rule_summaries ers ON erc.uuid = ers.ecr_rr_conditions_id where $[whereClause] order by ed.report_date DESC OFFSET $[startIndex] ROWS FETCH NEXT $[itemsPerPage] ROWS ONLY", + "SELECT ed.eICR_ID, ed.patient_name_first, ed.patient_name_last, ed.patient_birth_date, ed.date_created, ed.report_date, erc.condition, ers.rule_summary, ed.report_date FROM ecr_data ed LEFT JOIN ecr_rr_conditions erc ON ed.eICR_ID = erc.eICR_ID LEFT JOIN ecr_rr_rule_summaries ers ON erc.uuid = ers.ecr_rr_conditions_id where $[whereClause] $[sortStatement] OFFSET $[startIndex] ROWS FETCH NEXT $[itemsPerPage] ROWS ONLY", { whereClause: expect.any(Object), startIndex, itemsPerPage, + sortStatement: expect.any(Object), }, ); expect(actual).toEqual([ @@ -211,15 +235,24 @@ describe("listEcrDataService", () => { database.manyOrNone = jest.fn(() => Promise.resolve([])); let startIndex = 0; let itemsPerPage = 25; + let columnName = "date_created"; + let direction = "DESC"; let searchTerm = "abc"; - await listEcrData(startIndex, itemsPerPage, searchTerm); + await listEcrData( + startIndex, + itemsPerPage, + columnName, + direction, + searchTerm, + ); expect(database.manyOrNone).toHaveBeenCalledOnce(); expect(database.manyOrNone).toHaveBeenCalledWith( - "SELECT ed.eICR_ID, ed.patient_name_first, ed.patient_name_last, ed.patient_birth_date, ed.date_created, ed.report_date, erc.condition, ers.rule_summary, ed.report_date FROM ecr_data ed LEFT JOIN ecr_rr_conditions erc ON ed.eICR_ID = erc.eICR_ID LEFT JOIN ecr_rr_rule_summaries ers ON erc.uuid = ers.ecr_rr_conditions_id where $[whereClause] order by ed.report_date DESC OFFSET $[startIndex] ROWS FETCH NEXT $[itemsPerPage] ROWS ONLY", + "SELECT ed.eICR_ID, ed.patient_name_first, ed.patient_name_last, ed.patient_birth_date, ed.date_created, ed.report_date, erc.condition, ers.rule_summary, ed.report_date FROM ecr_data ed LEFT JOIN ecr_rr_conditions erc ON ed.eICR_ID = erc.eICR_ID LEFT JOIN ecr_rr_rule_summaries ers ON erc.uuid = ers.ecr_rr_conditions_id where $[whereClause] $[sortStatement] OFFSET $[startIndex] ROWS FETCH NEXT $[itemsPerPage] ROWS ONLY", { whereClause: expect.any(Object), startIndex, itemsPerPage, + sortStatement: expect.any(Object), }, ); }); @@ -229,14 +262,23 @@ describe("listEcrDataService", () => { let startIndex = 0; let itemsPerPage = 25; let searchTerm = "O'Riley"; - await listEcrData(startIndex, itemsPerPage, searchTerm); + let columnName = "date_created"; + let direction = "DESC"; + await listEcrData( + startIndex, + itemsPerPage, + searchTerm, + columnName, + direction, + ); expect(database.manyOrNone).toHaveBeenCalledOnce(); expect(database.manyOrNone).toHaveBeenCalledWith( - "SELECT ed.eICR_ID, ed.patient_name_first, ed.patient_name_last, ed.patient_birth_date, ed.date_created, ed.report_date, erc.condition, ers.rule_summary, ed.report_date FROM ecr_data ed LEFT JOIN ecr_rr_conditions erc ON ed.eICR_ID = erc.eICR_ID LEFT JOIN ecr_rr_rule_summaries ers ON erc.uuid = ers.ecr_rr_conditions_id where $[whereClause] order by ed.report_date DESC OFFSET $[startIndex] ROWS FETCH NEXT $[itemsPerPage] ROWS ONLY", + "SELECT ed.eICR_ID, ed.patient_name_first, ed.patient_name_last, ed.patient_birth_date, ed.date_created, ed.report_date, erc.condition, ers.rule_summary, ed.report_date FROM ecr_data ed LEFT JOIN ecr_rr_conditions erc ON ed.eICR_ID = erc.eICR_ID LEFT JOIN ecr_rr_rule_summaries ers ON erc.uuid = ers.ecr_rr_conditions_id where $[whereClause] $[sortStatement] OFFSET $[startIndex] ROWS FETCH NEXT $[itemsPerPage] ROWS ONLY", { whereClause: expect.any(Object), startIndex, itemsPerPage, + sortStatement: expect.any(Object), }, ); }); diff --git a/containers/ecr-viewer/src/app/components/EcrTable.tsx b/containers/ecr-viewer/src/app/components/EcrTable.tsx index 754cccbee..1ed3ddec8 100644 --- a/containers/ecr-viewer/src/app/components/EcrTable.tsx +++ b/containers/ecr-viewer/src/app/components/EcrTable.tsx @@ -1,147 +1,50 @@ -import { Table } from "@trussworks/react-uswds"; -import { EcrDisplay, listEcrData } from "@/app/api/services/listEcrDataService"; -import { toSentenceCase } from "@/app/services/formatService"; +import React from "react"; +import { listEcrData } from "@/app/api/services/listEcrDataService"; -const basePath = - process.env.NODE_ENV === "production" ? process.env.NEXT_PUBLIC_BASEPATH : ""; +import { EcrTableClient } from "@/app/components/EcrTableClient"; /** * eCR Table * @param props - The properties passed to the component. * @param props.currentPage - The current page to be displayed * @param props.itemsPerPage - The number of items to be displayed in the table + * @param props.sortColumn - The column to sort by + * @param props.sortDirection - The direction to sort by * @param props.searchTerm - The search term used to list data * @returns - eCR Table element */ const EcrTable = async ({ currentPage, itemsPerPage, + sortColumn, + sortDirection, searchTerm, }: { currentPage: number; itemsPerPage: number; + sortColumn: string; + sortDirection: string; searchTerm?: string; }) => { - const renderPage = async (pageNumber: number) => { - const startIndex = (pageNumber - 1) * itemsPerPage; - const pageData = await listEcrData(startIndex, itemsPerPage, searchTerm); - return renderListEcrTableData(pageData); - }; - - const header = [ - { value: "Patient", className: "library-patient-column" }, - { value: "Received Date", className: "library-received-date-column" }, - { value: "Encounter Date", className: "library-encounter-date-column" }, - { value: "Reportable Condition", className: "library-condition-column" }, - { value: "RCKMS Rule Summary", className: "library-rule-column" }, - ]; - return ( -
- - - - {header.map((column) => ( - - ))} - - - {await renderPage(currentPage)} -
- {column.value} -
-
+ const startIndex = (currentPage - 1) * itemsPerPage; + + const data = await listEcrData( + startIndex, + itemsPerPage, + sortColumn, + sortDirection, + searchTerm, ); -}; - -/** - * Renders table rows given a list of eCRs. Each row contains an eCR ID linked to its - * individual eCR viewer page and the stored date. - * @param listFhirData - The list of eCRs to render. - * @returns An array of JSX table row elements representing the list of eCRs. - */ -const renderListEcrTableData = (listFhirData: EcrDisplay[]) => { - return listFhirData.map((item, index) => { - return formatRow(item, index); - }); -}; - -/** - * Formats a single row of the eCR table. - * @param item - The eCR data to be formatted. - * @param index - The index of the eCR data in the list. - * @returns A JSX table row element representing the eCR data. - */ -const formatRow = (item: EcrDisplay, index: number) => { - let patient_first_name = toSentenceCase(item.patient_first_name); - let patient_last_name = toSentenceCase(item.patient_last_name); - let createDateObj = new Date(item.date_created); - let createDateDate = formatDate(createDateObj); - let createDateTime = formatTime(createDateObj); - let patientReportDateObj = new Date(item.patient_report_date); - let patientReportDate = formatDate(patientReportDateObj); - let patientReportTime = formatTime(patientReportDateObj); return ( - - - - {patient_first_name} {patient_last_name} - -
-
{"DOB: " + item.patient_date_of_birth || ""}
- - - {createDateDate} -
- {createDateTime} - - - {patientReportDate} -
- {patientReportTime} - - {item.reportable_condition} - {item.rule_summary} - +
+ +
); }; -/** - * Formats a date object to a string in the format MM/DD/YYYY. - * @param date - The date object to be formatted. - * @returns A string in the format MM/DD/YYYY. - */ -const formatDate = (date: Date) => { - return date.toLocaleDateString("en-US"); -}; - -/** - * Formats a date object to a string in the format HH:MM AM/PM. - * @param date - The date object to be formatted. - * @returns A string in the format HH:MM AM/PM. - */ -const formatTime = (date: Date) => { - let hours = date.getHours(); - const minutes = date.getMinutes(); - const ampm = hours >= 12 ? "PM" : "AM"; - - hours = hours % 12; - hours = hours ? hours : 12; - - const minutesStr = minutes < 10 ? `0${minutes}` : minutes; - - return `${hours}:${minutesStr} ${ampm}`; -}; - export default EcrTable; diff --git a/containers/ecr-viewer/src/app/components/EcrTableClient.tsx b/containers/ecr-viewer/src/app/components/EcrTableClient.tsx new file mode 100644 index 000000000..88f4233e8 --- /dev/null +++ b/containers/ecr-viewer/src/app/components/EcrTableClient.tsx @@ -0,0 +1,307 @@ +"use client"; +import React, { useEffect, useState } from "react"; +import { Table } from "@trussworks/react-uswds"; +import { SortButton } from "@/app/components/SortButton"; +import { EcrDisplay } from "@/app/api/services/listEcrDataService"; +import { toSentenceCase } from "@/app/services/formatService"; +import { usePathname, useSearchParams, useRouter } from "next/navigation"; + +const basePath = + process.env.NODE_ENV === "production" ? process.env.NEXT_PUBLIC_BASEPATH : ""; + +type EcrTableClientProps = { + data: EcrDisplay[]; + sortColumn: string; + sortDirection: string; +}; + +interface SortPreferences { + columnId: string; + direction: string; +} + +const defaultPreferences = { + columnId: "date_created", + direction: "DESC", +}; + +/** + * + * @param props - The properties passed to the component. + * @param props.data - The data to be displayed in the table. + * @param props.sortColumn - The column to sort by. + * @param props.sortDirection - The direction to sort by. + * @returns - The JSX element representing the eCR table. + */ +export const EcrTableClient: React.FC = ({ + data, + sortColumn, + sortDirection, +}) => { + const searchParams = useSearchParams(); + const router = useRouter(); + const pathname = usePathname(); + + const [sortPreferences, setSortPreferences] = + useState(defaultPreferences); + const [sortedData, setSortedData] = useState(data); + + const [headers, setHeaders] = useState([ + { + id: "patient", + value: "Patient", + className: "library-patient-column", + dataSortable: true, + sortDirection: "", + }, + { + id: "date_created", + value: "Received Date", + className: "library-received-date-column", + dataSortable: true, + sortDirection: "", + }, + { + id: "report_date", + value: "Encounter Date", + className: "library-encounter-date-column", + dataSortable: true, + sortDirection: "", + }, + { + id: "reportable_condition", + value: "Reportable Condition", + className: "library-condition-colum", + dataSortable: false, + sortDirection: "", + }, + { + id: "rule_summary", + value: "RCKMS Rule Summary", + className: "library-rule-column", + dataSortable: false, + sortDirection: "", + }, + ]); + + /** + * Updates the URL with the current sort preferences. + */ + useEffect(() => { + const current = new URLSearchParams(Array.from(searchParams.entries())); + current.set("columnId", sortPreferences.columnId.toString()); + current.set("direction", sortPreferences.direction.toString()); + const search = current.toString(); + const query = search ? `?${search}` : ""; + router.push(`${pathname}${query}`); + }, [sortPreferences]); + + /** + * Updates the sort config from the server. + */ + useEffect(() => { + if (sortColumn) { + setHeaders((prevHeaders) => + prevHeaders.map((header) => { + if (header.id === sortColumn) { + // Toggle sortDirection for the matched column + return { + ...header, + sortDirection: + sortDirection || + (header.sortDirection === "ASC" ? "DESC" : "ASC"), + }; + } else { + return { + ...header, + sortDirection: "", + }; + } + }), + ); + } + }, [sortColumn, sortDirection]); + + /** + * Updates the sorted data from the server. + */ + useEffect(() => { + setSortedData(data); + }, [data]); + + /** + * Handles sorting the table data by a given column. + * @param columnId - The ID of the column to sort by. + * @param direction - The direction to sort by. + */ + const handleSort = (columnId: string, direction: string) => { + direction = direction === "ASC" ? "DESC" : "ASC"; + + const updatedSortPreferences: SortPreferences = { + ...sortPreferences, + columnId: columnId, + direction: direction, + }; + setSortPreferences(updatedSortPreferences); + localStorage.setItem( + "sortPreferences", + JSON.stringify(updatedSortPreferences), + ); + }; + + return ( +
+ + + + {headers.map((column) => + column.sortDirection ? ( + + ) : ( + + ), + )} + + + {renderListEcrTableData(sortedData)} +
+
+ {column.value} + +
+
+
+ {column.value} + {column.dataSortable ? ( + + ) : null} +
+
+
+ ); +}; + +type AriaSortType = "none" | "ascending" | "descending" | "other"; + +const getAriaSortValue = (sortDirection: string): AriaSortType => { + if (sortDirection !== "") { + return sortDirection === "ASC" ? "ascending" : "descending"; + } else { + return "none"; + } +}; + +/** + * Renders table rows given a list of eCRs. Each row contains an eCR ID linked to its + * individual eCR viewer page and the stor ed date. + * @param listFhirData - The list of eCRs to render. + * @returns An array of JSX table row elements representing the list of eCRs. + */ +const renderListEcrTableData = (listFhirData: EcrDisplay[]) => { + return listFhirData.map((item, index) => { + return formatRow(item, index); + }); +}; + +/** + * Formats a single row of the eCR table. + * @param item - The eCR data to be formatted. + * @param index - The index of the eCR data in the list. + * @returns A JSX table row element representing the eCR data. + */ +const formatRow = (item: EcrDisplay, index: number) => { + let patient_first_name = toSentenceCase(item.patient_first_name); + let patient_last_name = toSentenceCase(item.patient_last_name); + let createDateObj = new Date(item.date_created); + let createDateDate = formatDate(createDateObj); + let createDateTime = formatTime(createDateObj); + let patientReportDateObj = new Date(item.patient_report_date); + let patientReportDate = formatDate(patientReportDateObj); + let patientReportTime = formatTime(patientReportDateObj); + + return ( + + + + {patient_first_name} {patient_last_name} + +
+
{"DOB: " + item.patient_date_of_birth || ""}
+ + + {createDateDate} +
+ {createDateTime} + + + {patientReportDate} +
+ {patientReportTime} + + {item.reportable_condition} + {item.rule_summary} + + ); +}; + +/** + * Formats a date object to a string in the format MM/DD/YYYY. + * @param date - The date object to be formatted. + * @returns A string in the format MM/DD/YYYY. + */ +const formatDate = (date: Date) => { + return date.toLocaleDateString("en-US"); +}; + +/** + * Formats a date object to a string in the format HH:MM AM/PM. + * @param date - The date object to be formatted. + * @returns A string in the format HH:MM AM/PM. + */ +const formatTime = (date: Date) => { + let hours = date.getHours(); + const minutes = date.getMinutes(); + const ampm = hours >= 12 ? "PM" : "AM"; + + hours = hours % 12; + hours = hours ? hours : 12; + + const minutesStr = minutes < 10 ? `0${minutes}` : minutes; + + return `${hours}:${minutesStr} ${ampm}`; +}; diff --git a/containers/ecr-viewer/src/app/components/SortButton.tsx b/containers/ecr-viewer/src/app/components/SortButton.tsx new file mode 100644 index 000000000..8f0d7da3c --- /dev/null +++ b/containers/ecr-viewer/src/app/components/SortButton.tsx @@ -0,0 +1,96 @@ +"use client"; +import React from "react"; +import { Button } from "@trussworks/react-uswds"; + +type SortButtonProps = { + columnName: string; + className: string; + handleSort: (columnName: string, direction: string) => void; + direction: string; +}; + +/** + * Functional component for a sort button. + * @param props - Props containing button configurations. + * @param props.columnName - The name of the column to sort + * @param props.className - The class name of the button + * @param props.handleSort - The function to handle the click event + * @param props.direction - The direction to sort by + * @returns The JSX element representing the sort button. + */ +export const SortButton: React.FC = ({ + columnName, + className, + handleSort, + direction, +}) => { + const buttonSelector = `${columnName}-sort-button`; + const headerSelectorToSort = `${columnName}-header`; + + function resetArrowDirections() { + const arrowsToReset = document.querySelectorAll( + 'th[aria-sort="ascending"] button', + ); + arrowsToReset.forEach((arrow) => { + arrow.id !== buttonSelector + ? arrow.setAttribute( + "class", + "sort-button usa-button sortable-column margin-left-auto", + ) + : ""; + }); + } + + function changeArrowDirection() { + const buttons = document.querySelectorAll(`button#${buttonSelector}`); + buttons.forEach((button) => { + button.className === + "sort-button usa-button sortable-column margin-left-auto" + ? button.setAttribute( + "class", + "sort-button usa-button margin-left-auto sortable-asc-column margin-left-auto", + ) + : button.className === + "sort-button usa-button sortable-asc-column margin-left-auto" + ? button.setAttribute( + "class", + "sort-button usa-button sortable-desc-column margin-left-auto", + ) + : button.setAttribute( + "class", + "sort-button usa-button sortable-asc-column margin-left-auto", + ); + }); + } + + function resetHeaderMarker() { + const headersToReset = document.querySelectorAll(`th`); + headersToReset.forEach((header) => { + header.removeAttribute("aria-sort"); + }); + } + + function changeHeaderMarker() { + const headerToSet = document.querySelectorAll(`th#${headerSelectorToSort}`); + headerToSet.forEach((header) => + header.setAttribute("aria-sort", "ascending"), + ); + } + + return ( + + ); +}; diff --git a/containers/ecr-viewer/src/app/page.tsx b/containers/ecr-viewer/src/app/page.tsx index 9153dbcb5..a32c76463 100644 --- a/containers/ecr-viewer/src/app/page.tsx +++ b/containers/ecr-viewer/src/app/page.tsx @@ -18,6 +18,8 @@ const HomePage = async ({ }) => { const currentPage = Number(searchParams?.page) || 1; const itemsPerPage = Number(searchParams?.itemsPerPage) || 25; + const sortColumn = (searchParams?.columnId as string) || "date_created"; + const sortDirection = (searchParams?.direction as string) || "DESC"; const searchTerm = searchParams?.search as string | undefined; const isNonIntegratedViewer = @@ -44,6 +46,8 @@ const HomePage = async ({ diff --git a/containers/ecr-viewer/src/app/tests/components/EcrTable.test.tsx b/containers/ecr-viewer/src/app/tests/components/EcrTable.test.tsx index 0252eca69..f8e2e1ad2 100644 --- a/containers/ecr-viewer/src/app/tests/components/EcrTable.test.tsx +++ b/containers/ecr-viewer/src/app/tests/components/EcrTable.test.tsx @@ -2,9 +2,16 @@ import { axe } from "jest-axe"; import { render } from "@testing-library/react"; import EcrTable from "@/app/components/EcrTable"; import { EcrDisplay, listEcrData } from "@/app/api/services/listEcrDataService"; +import router from "next-router-mock"; jest.mock("../../api/services/listEcrDataService"); +jest.mock("next/navigation", () => ({ + useRouter: () => router, + usePathname: () => router.pathname, + useSearchParams: () => new URLSearchParams(router.asPath.split("?")[1] || ""), +})); + describe("EcrTable", () => { const mockedListEcrData = jest.mocked(listEcrData); const mockData: EcrDisplay[] = Array.from({ length: 25 }, (_, i) => ({ @@ -21,12 +28,20 @@ describe("EcrTable", () => { beforeEach(() => { jest.resetAllMocks(); + router.setCurrentUrl( + "/?itemsPerPage=25&columnId=report_date&direction=ASC&page=1", + ); }); it("should match snapshot", async () => { mockedListEcrData.mockResolvedValue(mockData); const { container } = render( - await EcrTable({ currentPage: 1, itemsPerPage: 25 }), + await EcrTable({ + currentPage: 1, + itemsPerPage: 25, + sortColumn: "date_created", + sortDirection: "DESC", + }), ); expect(container).toMatchSnapshot(); }); @@ -34,7 +49,12 @@ describe("EcrTable", () => { it("should pass accessibility", async () => { mockedListEcrData.mockResolvedValue(mockData); const { container } = render( - await EcrTable({ currentPage: 1, itemsPerPage: 25 }), + await EcrTable({ + currentPage: 1, + itemsPerPage: 25, + sortColumn: "date_created", + sortDirection: "DESC", + }), ); expect(await axe(container)).toHaveNoViolations(); }); @@ -43,10 +63,22 @@ describe("EcrTable", () => { mockedListEcrData.mockResolvedValue(mockData); render( - await EcrTable({ currentPage: 1, itemsPerPage: 25, searchTerm: "blah" }), + await EcrTable({ + currentPage: 1, + itemsPerPage: 25, + sortColumn: "date_created", + sortDirection: "DESC", + searchTerm: "blah", + }), ); expect(mockedListEcrData).toHaveBeenCalledTimes(1); - expect(mockedListEcrData).toHaveBeenCalledWith(0, 25, "blah"); + expect(mockedListEcrData).toHaveBeenCalledWith( + 0, + 25, + "date_created", + "DESC", + "blah", + ); }); }); diff --git a/containers/ecr-viewer/src/app/tests/components/__snapshots__/EcrTable.test.tsx.snap b/containers/ecr-viewer/src/app/tests/components/__snapshots__/EcrTable.test.tsx.snap index c6669d9ff..d1c47ed59 100644 --- a/containers/ecr-viewer/src/app/tests/components/__snapshots__/EcrTable.test.tsx.snap +++ b/containers/ecr-viewer/src/app/tests/components/__snapshots__/EcrTable.test.tsx.snap @@ -3,826 +3,883 @@ exports[`EcrTable should match snapshot 1`] = `
- - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Patient - - Received Date - - Encounter Date - - Reportable Condition - - RCKMS Rule Summary -
- +
- First-1 - - Last-1 - -
-
- DOB: 2000-01-01 -
- -
- 12/31/2020 -
- 7:00 PM -
- 12/31/2020 -
- 7:00 PM -
- reportable-condition-1 - - rule-summary-1 -
- + Patient + - First-2 - - Last-2 - -
-
- DOB: 2000-01-02 -
- -
- 1/1/2021 -
- 7:00 PM -
- 1/1/2021 -
- 7:00 PM -
- reportable-condition-2 - - rule-summary-2 -
- + Received Date + - First-3 - - Last-3 - -
-
- DOB: 2000-01-03 -
- -
- 1/2/2021 -
- 7:00 PM -
- 1/2/2021 -
- 7:00 PM -
- reportable-condition-3 - - rule-summary-3 -
- + Encounter Date + - First-4 - - Last-4 - -
-
- DOB: 2000-01-04 -
- -
- 1/3/2021 -
- 7:00 PM -
- 1/3/2021 -
- 7:00 PM -
- reportable-condition-4 - - rule-summary-4 -
- + Reportable Condition + + + - First-5 - - Last-5 - -
-
- DOB: 2000-01-05 -
- -
- 1/4/2021 -
- 7:00 PM -
- 1/4/2021 -
- 7:00 PM -
- reportable-condition-5 - - rule-summary-5 -
- - First-6 - - Last-6 - -
-
- DOB: 2000-01-06 -
-
- 1/5/2021 -
- 7:00 PM -
- 1/5/2021 -
- 7:00 PM -
- reportable-condition-6 - - rule-summary-6 -
- - First-7 - - Last-7 - -
-
- DOB: 2000-01-07 -
-
- 1/6/2021 -
- 7:00 PM -
- 1/6/2021 -
- 7:00 PM -
- reportable-condition-7 - - rule-summary-7 -
- - First-8 - - Last-8 - -
-
- DOB: 2000-01-08 -
-
- 1/7/2021 -
- 7:00 PM -
- 1/7/2021 -
- 7:00 PM -
- reportable-condition-8 - - rule-summary-8 -
- - First-9 - - Last-9 - -
-
- DOB: 2000-01-09 -
-
- 1/8/2021 -
- 7:00 PM -
- 1/8/2021 -
- 7:00 PM -
- reportable-condition-9 - - rule-summary-9 -
- - First-10 - - Last-10 - -
-
- DOB: 2000-01-01 -
-
- 12/31/2020 -
- 7:00 PM -
- 12/31/2020 -
- 7:00 PM -
- reportable-condition-10 - - rule-summary-10 -
- - First-11 - - Last-11 - -
-
- DOB: 2000-01-02 -
-
- 1/1/2021 -
- 7:00 PM -
- 1/1/2021 -
- 7:00 PM -
- reportable-condition-11 - - rule-summary-11 -
- - First-12 - - Last-12 - -
-
- DOB: 2000-01-03 -
-
- 1/2/2021 -
- 7:00 PM -
- 1/2/2021 -
- 7:00 PM -
- reportable-condition-12 - - rule-summary-12 -
- - First-13 - - Last-13 - -
-
- DOB: 2000-01-04 -
-
- 1/3/2021 -
- 7:00 PM -
- 1/3/2021 -
- 7:00 PM -
- reportable-condition-13 - - rule-summary-13 -
- - First-14 - - Last-14 - -
-
- DOB: 2000-01-05 -
-
- 1/4/2021 -
- 7:00 PM -
- 1/4/2021 -
- 7:00 PM -
- reportable-condition-14 - - rule-summary-14 -
- - First-15 - - Last-15 - -
-
- DOB: 2000-01-06 -
-
- 1/5/2021 -
- 7:00 PM -
- 1/5/2021 -
- 7:00 PM -
- reportable-condition-15 - - rule-summary-15 -
- - First-16 - - Last-16 - -
-
- DOB: 2000-01-07 -
-
- 1/6/2021 -
- 7:00 PM -
- 1/6/2021 -
- 7:00 PM -
- reportable-condition-16 - - rule-summary-16 -
- - First-17 - - Last-17 - -
-
- DOB: 2000-01-08 -
-
- 1/7/2021 -
- 7:00 PM -
- 1/7/2021 -
- 7:00 PM -
- reportable-condition-17 - - rule-summary-17 -
- - First-18 - - Last-18 - -
-
- DOB: 2000-01-09 -
-
- 1/8/2021 -
- 7:00 PM -
- 1/8/2021 -
- 7:00 PM -
- reportable-condition-18 - - rule-summary-18 -
- - First-19 - - Last-19 - -
-
- DOB: 2000-01-01 -
-
- 12/31/2020 -
- 7:00 PM -
- 12/31/2020 -
- 7:00 PM -
- reportable-condition-19 - - rule-summary-19 -
- - First-20 - - Last-20 - -
-
- DOB: 2000-01-02 -
-
- 1/1/2021 -
- 7:00 PM -
- 1/1/2021 -
- 7:00 PM -
- reportable-condition-20 - - rule-summary-20 -
- - First-21 - - Last-21 - -
-
- DOB: 2000-01-03 -
-
- 1/2/2021 -
- 7:00 PM -
- 1/2/2021 -
- 7:00 PM -
- reportable-condition-21 - - rule-summary-21 -
- - First-22 - - Last-22 - -
-
- DOB: 2000-01-04 -
-
- 1/3/2021 -
- 7:00 PM -
- 1/3/2021 -
- 7:00 PM -
- reportable-condition-22 - - rule-summary-22 -
- - First-23 - - Last-23 - -
-
- DOB: 2000-01-05 -
-
- 1/4/2021 -
- 7:00 PM -
- 1/4/2021 -
- 7:00 PM -
- reportable-condition-23 - - rule-summary-23 -
- - First-24 - - Last-24 - -
-
- DOB: 2000-01-06 -
-
- 1/5/2021 -
- 7:00 PM -
- 1/5/2021 -
- 7:00 PM -
- reportable-condition-24 - - rule-summary-24 -
- - First-25 - - Last-25 - -
-
- DOB: 2000-01-07 -
-
- 1/6/2021 -
- 7:00 PM -
- 1/6/2021 -
- 7:00 PM -
- reportable-condition-25 - - rule-summary-25 -
+
+ RCKMS Rule Summary +
+ + + + + + + + First-1 + + Last-1 + +
+
+ DOB: 2000-01-01 +
+ + + 12/31/2020 +
+ 7:00 PM + + + 12/31/2020 +
+ 7:00 PM + + + reportable-condition-1 + + + rule-summary-1 + + + + + + First-2 + + Last-2 + +
+
+ DOB: 2000-01-02 +
+ + + 1/1/2021 +
+ 7:00 PM + + + 1/1/2021 +
+ 7:00 PM + + + reportable-condition-2 + + + rule-summary-2 + + + + + + First-3 + + Last-3 + +
+
+ DOB: 2000-01-03 +
+ + + 1/2/2021 +
+ 7:00 PM + + + 1/2/2021 +
+ 7:00 PM + + + reportable-condition-3 + + + rule-summary-3 + + + + + + First-4 + + Last-4 + +
+
+ DOB: 2000-01-04 +
+ + + 1/3/2021 +
+ 7:00 PM + + + 1/3/2021 +
+ 7:00 PM + + + reportable-condition-4 + + + rule-summary-4 + + + + + + First-5 + + Last-5 + +
+
+ DOB: 2000-01-05 +
+ + + 1/4/2021 +
+ 7:00 PM + + + 1/4/2021 +
+ 7:00 PM + + + reportable-condition-5 + + + rule-summary-5 + + + + + + First-6 + + Last-6 + +
+
+ DOB: 2000-01-06 +
+ + + 1/5/2021 +
+ 7:00 PM + + + 1/5/2021 +
+ 7:00 PM + + + reportable-condition-6 + + + rule-summary-6 + + + + + + First-7 + + Last-7 + +
+
+ DOB: 2000-01-07 +
+ + + 1/6/2021 +
+ 7:00 PM + + + 1/6/2021 +
+ 7:00 PM + + + reportable-condition-7 + + + rule-summary-7 + + + + + + First-8 + + Last-8 + +
+
+ DOB: 2000-01-08 +
+ + + 1/7/2021 +
+ 7:00 PM + + + 1/7/2021 +
+ 7:00 PM + + + reportable-condition-8 + + + rule-summary-8 + + + + + + First-9 + + Last-9 + +
+
+ DOB: 2000-01-09 +
+ + + 1/8/2021 +
+ 7:00 PM + + + 1/8/2021 +
+ 7:00 PM + + + reportable-condition-9 + + + rule-summary-9 + + + + + + First-10 + + Last-10 + +
+
+ DOB: 2000-01-01 +
+ + + 12/31/2020 +
+ 7:00 PM + + + 12/31/2020 +
+ 7:00 PM + + + reportable-condition-10 + + + rule-summary-10 + + + + + + First-11 + + Last-11 + +
+
+ DOB: 2000-01-02 +
+ + + 1/1/2021 +
+ 7:00 PM + + + 1/1/2021 +
+ 7:00 PM + + + reportable-condition-11 + + + rule-summary-11 + + + + + + First-12 + + Last-12 + +
+
+ DOB: 2000-01-03 +
+ + + 1/2/2021 +
+ 7:00 PM + + + 1/2/2021 +
+ 7:00 PM + + + reportable-condition-12 + + + rule-summary-12 + + + + + + First-13 + + Last-13 + +
+
+ DOB: 2000-01-04 +
+ + + 1/3/2021 +
+ 7:00 PM + + + 1/3/2021 +
+ 7:00 PM + + + reportable-condition-13 + + + rule-summary-13 + + + + + + First-14 + + Last-14 + +
+
+ DOB: 2000-01-05 +
+ + + 1/4/2021 +
+ 7:00 PM + + + 1/4/2021 +
+ 7:00 PM + + + reportable-condition-14 + + + rule-summary-14 + + + + + + First-15 + + Last-15 + +
+
+ DOB: 2000-01-06 +
+ + + 1/5/2021 +
+ 7:00 PM + + + 1/5/2021 +
+ 7:00 PM + + + reportable-condition-15 + + + rule-summary-15 + + + + + + First-16 + + Last-16 + +
+
+ DOB: 2000-01-07 +
+ + + 1/6/2021 +
+ 7:00 PM + + + 1/6/2021 +
+ 7:00 PM + + + reportable-condition-16 + + + rule-summary-16 + + + + + + First-17 + + Last-17 + +
+
+ DOB: 2000-01-08 +
+ + + 1/7/2021 +
+ 7:00 PM + + + 1/7/2021 +
+ 7:00 PM + + + reportable-condition-17 + + + rule-summary-17 + + + + + + First-18 + + Last-18 + +
+
+ DOB: 2000-01-09 +
+ + + 1/8/2021 +
+ 7:00 PM + + + 1/8/2021 +
+ 7:00 PM + + + reportable-condition-18 + + + rule-summary-18 + + + + + + First-19 + + Last-19 + +
+
+ DOB: 2000-01-01 +
+ + + 12/31/2020 +
+ 7:00 PM + + + 12/31/2020 +
+ 7:00 PM + + + reportable-condition-19 + + + rule-summary-19 + + + + + + First-20 + + Last-20 + +
+
+ DOB: 2000-01-02 +
+ + + 1/1/2021 +
+ 7:00 PM + + + 1/1/2021 +
+ 7:00 PM + + + reportable-condition-20 + + + rule-summary-20 + + + + + + First-21 + + Last-21 + +
+
+ DOB: 2000-01-03 +
+ + + 1/2/2021 +
+ 7:00 PM + + + 1/2/2021 +
+ 7:00 PM + + + reportable-condition-21 + + + rule-summary-21 + + + + + + First-22 + + Last-22 + +
+
+ DOB: 2000-01-04 +
+ + + 1/3/2021 +
+ 7:00 PM + + + 1/3/2021 +
+ 7:00 PM + + + reportable-condition-22 + + + rule-summary-22 + + + + + + First-23 + + Last-23 + +
+
+ DOB: 2000-01-05 +
+ + + 1/4/2021 +
+ 7:00 PM + + + 1/4/2021 +
+ 7:00 PM + + + reportable-condition-23 + + + rule-summary-23 + + + + + + First-24 + + Last-24 + +
+
+ DOB: 2000-01-06 +
+ + + 1/5/2021 +
+ 7:00 PM + + + 1/5/2021 +
+ 7:00 PM + + + reportable-condition-24 + + + rule-summary-24 + + + + + + First-25 + + Last-25 + +
+
+ DOB: 2000-01-07 +
+ + + 1/6/2021 +
+ 7:00 PM + + + 1/6/2021 +
+ 7:00 PM + + + reportable-condition-25 + + + rule-summary-25 + + + + +
`; diff --git a/containers/ecr-viewer/src/styles/custom-styles.scss b/containers/ecr-viewer/src/styles/custom-styles.scss index c80f43d0f..86c19b8f8 100644 --- a/containers/ecr-viewer/src/styles/custom-styles.scss +++ b/containers/ecr-viewer/src/styles/custom-styles.scss @@ -170,6 +170,45 @@ h4 { } } +.sort-button{ + border: none; + outline: none; + transition: none; + &:hover{ + outline: none; + background-color: transparent; /* Removes the hover background */ + color: inherit; /* Keeps the text color unchanged */ + } + &:active { + outline: none; + background-color: inherit; /* Keeps the original background color */ + color: inherit; /* Keeps the text color unchanged */ + } + &:focus { + outline: none; + background-color: inherit; /* Removes fill after click */ + } +} + +.sortable-column{ + background-color: transparent; + @include add-background-svg("usa-icons/sort_arrow"); +} + +.sortable-desc-column{ + background-color: transparent; + @include add-background-svg("usa-icons/arrow_downward"); +} + +.sortable-asc-column{ + background-color: transparent; + @include add-background-svg("usa-icons/arrow_upward"); +} + +.ecr-client-wrapper { + height: calc(100% - 4rem); +} + .ecr-library-wrapper { height: calc(100% - 4rem); } diff --git a/package-lock.json b/package-lock.json index b65384fc7..85327d9ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,6 +52,7 @@ "mssql": "^11.0.1", "next": "^14.2.14", "next-auth": "^4.24.7", + "next-router-mock": "^0.9.13", "pg-promise": "^11.6.0", "react": "^18", "react-dom": "^18", @@ -1960,11 +1961,6 @@ "node": ">=6.9.0" } }, - "node_modules/@balena/dockerignore": { - "version": "1.0.2", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "dev": true, @@ -2051,15 +2047,6 @@ "ms": "^2.1.1" } }, - "node_modules/@emnapi/runtime": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz", - "integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@es-joy/jsdoccomment": { "version": "0.43.0", "dev": true, @@ -2239,348 +2226,6 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", - "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.0.4" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", - "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.0.4" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", - "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", - "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", - "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", - "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", - "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", - "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", - "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", - "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", - "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.0.5" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", - "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.0.4" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", - "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.0.4" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", - "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.0.4" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", - "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", - "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.0.4" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", - "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", - "cpu": [ - "wasm32" - ], - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.2.0" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", - "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", - "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "dev": true, @@ -4724,8 +4369,9 @@ }, "node_modules/@playwright/test": { "version": "1.45.2", - "devOptional": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "playwright": "1.45.2" }, @@ -5937,25 +5583,6 @@ "@types/node": "*" } }, - "node_modules/@types/docker-modem": { - "version": "3.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/ssh2": "*" - } - }, - "node_modules/@types/dockerode": { - "version": "3.3.29", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/docker-modem": "*", - "@types/node": "*", - "@types/ssh2": "*" - } - }, "node_modules/@types/eslint": { "version": "8.56.10", "dev": true, @@ -6085,11 +5712,6 @@ "@types/node": "*" } }, - "node_modules/@types/mocha": { - "version": "10.0.7", - "dev": true, - "license": "MIT" - }, "node_modules/@types/mssql": { "version": "9.1.5", "resolved": "https://registry.npmjs.org/@types/mssql/-/mssql-9.1.5.tgz", @@ -6117,15 +5739,6 @@ "undici-types": "~5.26.4" } }, - "node_modules/@types/node-fetch": { - "version": "2.6.11", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, "node_modules/@types/pg": { "version": "8.11.8", "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.8.tgz", @@ -6290,6 +5903,7 @@ }, "node_modules/@types/sinonjs__fake-timers": { "version": "8.1.5", + "dev": true, "license": "MIT" }, "node_modules/@types/sizzle": { @@ -6298,30 +5912,6 @@ "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", "dev": true }, - "node_modules/@types/ssh2": { - "version": "1.15.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "^18.11.18" - } - }, - "node_modules/@types/ssh2-streams": { - "version": "0.1.12", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/ssh2/node_modules/@types/node": { - "version": "18.19.33", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, "node_modules/@types/stack-utils": { "version": "2.0.3", "dev": true, @@ -6345,11 +5935,6 @@ "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" }, - "node_modules/@types/uuid": { - "version": "9.0.8", - "dev": true, - "license": "MIT" - }, "node_modules/@types/yargs": { "version": "17.0.32", "dev": true, @@ -6565,6 +6150,7 @@ "resolved": "https://registry.npmjs.org/@uswds/uswds/-/uswds-3.9.0.tgz", "integrity": "sha512-8THm36j7iLjrDiI1D0C6b3hHsmM/Sy5Iiz+IjE+i/gYzVUMG9XVthxAZYonhU97Q1b079n6nYwlUmDSYowJecQ==", "license": "SEE LICENSE IN LICENSE.md", + "peer": true, "dependencies": { "object-assign": "4.1.1", "receptor": "1.0.0", @@ -6790,95 +6376,6 @@ } ] }, - "node_modules/archiver": { - "version": "5.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "archiver-utils": "^2.1.0", - "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", - "readdir-glob": "^1.1.2", - "tar-stream": "^2.2.0", - "zip-stream": "^4.1.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/archiver-utils": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/archiver-utils/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/archiver-utils/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/archiver-utils/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/archiver/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/are-docs-informative": { "version": "0.0.2", "dev": true, @@ -7056,11 +6553,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/asap": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, "node_modules/asn1": { "version": "0.2.6", "dev": true, @@ -7085,14 +6577,6 @@ "node": ">=0.8" } }, - "node_modules/assertion-error": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/ast-types-flow": { "version": "0.0.8", "dev": true, @@ -7112,13 +6596,9 @@ "dev": true, "license": "MIT" }, - "node_modules/async-lock": { - "version": "1.4.1", - "dev": true, - "license": "MIT" - }, "node_modules/asynckit": { "version": "0.4.0", + "dev": true, "license": "MIT" }, "node_modules/at-least-node": { @@ -7213,17 +6693,6 @@ "node": ">=4" } }, - "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/axobject-query": { "version": "3.2.1", "dev": true, @@ -7232,11 +6701,6 @@ "dequal": "^2.0.3" } }, - "node_modules/b4a": { - "version": "1.6.6", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/babel-jest": { "version": "29.7.0", "dev": true, @@ -7351,47 +6815,6 @@ "dev": true, "license": "MIT" }, - "node_modules/bare-events": { - "version": "2.2.2", - "dev": true, - "license": "Apache-2.0", - "optional": true - }, - "node_modules/bare-fs": { - "version": "2.3.0", - "dev": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-events": "^2.0.0", - "bare-path": "^2.0.0", - "bare-stream": "^1.0.0" - } - }, - "node_modules/bare-os": { - "version": "2.3.0", - "dev": true, - "license": "Apache-2.0", - "optional": true - }, - "node_modules/bare-path": { - "version": "2.1.3", - "dev": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-os": "^2.1.0" - } - }, - "node_modules/bare-stream": { - "version": "1.0.0", - "dev": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "streamx": "^2.16.1" - } - }, "node_modules/base64-js": { "version": "1.5.1", "funding": [ @@ -7437,29 +6860,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bl": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/blob-util": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", @@ -7497,11 +6897,6 @@ "node": ">=8" } }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "dev": true, - "license": "ISC" - }, "node_modules/browserslist": { "version": "4.23.0", "dev": true, @@ -7608,14 +7003,6 @@ "node": ">= 0.10.x" } }, - "node_modules/buildcheck": { - "version": "0.0.6", - "dev": true, - "optional": true, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/busboy": { "version": "1.6.0", "dependencies": { @@ -7625,14 +7012,6 @@ "node": ">=10.16.0" } }, - "node_modules/byline": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cachedir": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", @@ -7700,23 +7079,6 @@ "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, - "node_modules/chai": { - "version": "4.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/chalk": { "version": "4.1.2", "license": "MIT", @@ -7739,17 +7101,6 @@ "node": ">=10" } }, - "node_modules/check-error": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, "node_modules/check-more-types": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", @@ -7793,11 +7144,6 @@ "node": ">= 6" } }, - "node_modules/chownr": { - "version": "1.1.4", - "dev": true, - "license": "ISC" - }, "node_modules/ci-info": { "version": "3.9.0", "dev": true, @@ -7903,14 +7249,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "engines": { - "node": ">=6" - } - }, "node_modules/co": { "version": "4.6.0", "dev": true, @@ -7936,17 +7274,6 @@ "dev": true, "license": "MIT" }, - "node_modules/color": { - "version": "4.2.3", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "license": "MIT", @@ -7961,14 +7288,6 @@ "version": "1.1.4", "license": "MIT" }, - "node_modules/color-string": { - "version": "1.9.1", - "license": "MIT", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -7977,6 +7296,7 @@ }, "node_modules/combined-stream": { "version": "1.0.8", + "dev": true, "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -8011,41 +7331,6 @@ "node": ">=4.0.0" } }, - "node_modules/component-emitter": { - "version": "1.3.1", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/compress-commons": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.2", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/compress-commons/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/concat-map": { "version": "0.0.1", "dev": true, @@ -8106,64 +7391,10 @@ "node": ">= 0.6" } }, - "node_modules/cookiejar": { - "version": "2.1.4", - "dev": true, - "license": "MIT" - }, "node_modules/core-util-is": { "version": "1.0.3", "license": "MIT" }, - "node_modules/cpu-features": { - "version": "0.0.10", - "dev": true, - "hasInstallScript": true, - "optional": true, - "dependencies": { - "buildcheck": "~0.0.6", - "nan": "^2.19.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/crc-32": { - "version": "1.2.2", - "dev": true, - "license": "Apache-2.0", - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/crc32-stream": { - "version": "4.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/crc32-stream/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/create-jest": { "version": "29.7.0", "dev": true, @@ -8439,17 +7670,6 @@ } } }, - "node_modules/decamelize": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/decimal.js": { "version": "10.4.3", "dev": true, @@ -8468,48 +7688,6 @@ } } }, - "node_modules/deep-eql": { - "version": "4.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-equal": { - "version": "2.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/deep-is": { "version": "0.1.4", "dev": true, @@ -8564,6 +7742,7 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -8576,13 +7755,6 @@ "node": ">=6" } }, - "node_modules/detect-libc": { - "version": "2.0.3", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "dev": true, @@ -8591,15 +7763,6 @@ "node": ">=8" } }, - "node_modules/dezalgo": { - "version": "1.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, "node_modules/diff": { "version": "5.2.0", "dev": true, @@ -8627,68 +7790,6 @@ "node": ">=8" } }, - "node_modules/docker-compose": { - "version": "0.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "yaml": "^2.2.2" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/docker-modem": { - "version": "3.0.8", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "debug": "^4.1.1", - "readable-stream": "^3.5.0", - "split-ca": "^1.0.1", - "ssh2": "^1.11.0" - }, - "engines": { - "node": ">= 8.0" - } - }, - "node_modules/docker-modem/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/dockerode": { - "version": "3.3.5", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@balena/dockerignore": "^1.0.2", - "docker-modem": "^3.0.0", - "tar-fs": "~2.0.1" - }, - "engines": { - "node": ">= 8.0" - } - }, - "node_modules/dockerode/node_modules/tar-fs": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.0.0" - } - }, "node_modules/doctrine": { "version": "3.0.0", "dev": true, @@ -8766,6 +7867,7 @@ "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, "engines": { "node": ">=12" }, @@ -8823,6 +7925,7 @@ "node_modules/element-closest": { "version": "2.0.2", "license": "CC0-1.0", + "peer": true, "engines": { "node": ">=4.0.0" } @@ -8987,25 +8090,6 @@ "node": ">= 0.4" } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-iterator-helpers": { "version": "1.0.19", "dev": true, @@ -9831,11 +8915,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "dev": true, - "license": "MIT" - }, "node_modules/fast-glob": { "version": "3.3.2", "dev": true, @@ -9872,11 +8951,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "dev": true, - "license": "MIT" - }, "node_modules/fast-xml-parser": { "version": "4.4.1", "funding": [ @@ -10053,14 +9127,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flat": { - "version": "5.0.2", - "dev": true, - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, "node_modules/flat-cache": { "version": "3.2.0", "dev": true, @@ -10083,6 +9149,7 @@ "version": "7.6.0", "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.0.tgz", "integrity": "sha512-1td0l3pMkWJLFipobUcGaf+5DTY4PLDDrcqoSaKP8ediO/CoWCCYk/fT/Y2A4e6TNB+Sh6clRJCjOPPnKoNHnQ==", + "peer": true, "dependencies": { "tabbable": "^6.2.0" } @@ -10091,6 +9158,7 @@ "version": "10.3.0", "resolved": "https://registry.npmjs.org/focus-trap-react/-/focus-trap-react-10.3.0.tgz", "integrity": "sha512-XrCTj44uNE0clTA47y1AbIb7tM7w6+zi6WrJzb4RxRe3uAIIivkBCwlsCqe7R3vPRT/LCQzfe4+N/KjtJMQMgw==", + "peer": true, "dependencies": { "focus-trap": "^7.6.0", "tabbable": "^6.2.0" @@ -10101,24 +9169,6 @@ "react-dom": ">=16.3.0" } }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/for-each": { "version": "0.3.3", "dev": true, @@ -10164,6 +9214,7 @@ }, "node_modules/form-data": { "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -10174,19 +9225,6 @@ "node": ">= 6" } }, - "node_modules/formidable": { - "version": "3.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "dezalgo": "^1.0.4", - "hexoid": "^1.0.0", - "once": "^1.4.0" - }, - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" - } - }, "node_modules/forwarded-parse": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", @@ -10205,11 +9243,6 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -10328,14 +9361,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/get-intrinsic": { "version": "1.2.4", "dev": true, @@ -10362,17 +9387,6 @@ "node": ">=8.0.0" } }, - "node_modules/get-port": { - "version": "5.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -10620,14 +9634,6 @@ "node": ">= 0.4" } }, - "node_modules/he": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, "node_modules/hexer": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/hexer/-/hexer-1.5.0.tgz", @@ -10653,14 +9659,6 @@ "node": ">= 0.6.0" } }, - "node_modules/hexoid": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/html-dom-parser": { "version": "5.0.8", "license": "MIT", @@ -10920,21 +9918,6 @@ "node": ">= 0.4" } }, - "node_modules/is-arguments": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-array-buffer": { "version": "3.0.4", "dev": true, @@ -11225,14 +10208,6 @@ "node": ">=8" } }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -12872,7 +11847,8 @@ }, "node_modules/keyboardevent-key-polyfill": { "version": "1.1.0", - "license": "CC0-1.0" + "license": "CC0-1.0", + "peer": true }, "node_modules/keyv": { "version": "4.5.4", @@ -12915,17 +11891,6 @@ "node": "> 0.8" } }, - "node_modules/lazystream": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "^2.0.5" - }, - "engines": { - "node": ">= 0.6.3" - } - }, "node_modules/leven": { "version": "3.1.0", "dev": true, @@ -13019,21 +11984,6 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.difference": { - "version": "4.5.0", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.get": { "version": "4.4.2", "license": "MIT" @@ -13083,11 +12033,6 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, - "node_modules/lodash.union": { - "version": "4.6.0", - "dev": true, - "license": "MIT" - }, "node_modules/log-symbols": { "version": "4.1.0", "dev": true, @@ -13191,14 +12136,6 @@ "loose-envify": "cli.js" } }, - "node_modules/loupe": { - "version": "2.3.7", - "dev": true, - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.1" - } - }, "node_modules/lru-cache": { "version": "5.1.1", "dev": true, @@ -13244,7 +12181,8 @@ }, "node_modules/matches-selector": { "version": "1.2.0", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/merge-stream": { "version": "2.0.0", @@ -13259,14 +12197,6 @@ "node": ">= 8" } }, - "node_modules/methods": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -13280,19 +12210,9 @@ "node": ">=8.6" } }, - "node_modules/mime": { - "version": "2.6.0", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/mime-db": { "version": "1.52.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -13300,6 +12220,7 @@ }, "node_modules/mime-types": { "version": "2.1.35", + "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -13353,155 +12274,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "dev": true, - "license": "MIT" - }, - "node_modules/mocha": { - "version": "10.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.3", - "browser-stdout": "^1.3.1", - "chokidar": "^3.5.3", - "debug": "^4.3.5", - "diff": "^5.2.0", - "escape-string-regexp": "^4.0.0", - "find-up": "^5.0.0", - "glob": "^8.1.0", - "he": "^1.2.0", - "js-yaml": "^4.1.0", - "log-symbols": "^4.1.0", - "minimatch": "^5.1.6", - "ms": "^2.1.3", - "serialize-javascript": "^6.0.2", - "strip-json-comments": "^3.1.1", - "supports-color": "^8.1.1", - "workerpool": "^6.5.1", - "yargs": "^16.2.0", - "yargs-parser": "^20.2.9", - "yargs-unparser": "^2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/mocha/node_modules/cliui": { - "version": "7.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "8.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.1.6", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/node_modules/wrap-ansi": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.9", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, "node_modules/module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", @@ -13538,12 +12310,6 @@ "node": ">=16" } }, - "node_modules/nan": { - "version": "2.19.0", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/nanoid": { "version": "3.3.7", "funding": [ @@ -13668,6 +12434,15 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/next-router-mock": { + "version": "0.9.13", + "resolved": "https://registry.npmjs.org/next-router-mock/-/next-router-mock-0.9.13.tgz", + "integrity": "sha512-906n2RRaE6Y28PfYJbaz5XZeJ6Tw8Xz1S6E31GGwZ0sXB6/XjldD1/2azn1ZmBmRk5PQRkzjg+n+RHZe5xQzWA==", + "peerDependencies": { + "next": ">=10.0.0", + "react": ">=17.0.0" + } + }, "node_modules/next/node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", @@ -13818,21 +12593,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-is": { - "version": "1.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object-keys": { "version": "1.1.1", "dev": true, @@ -14215,14 +12975,6 @@ "node": ">=8" } }, - "node_modules/pathval": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -14429,8 +13181,9 @@ }, "node_modules/playwright": { "version": "1.45.2", - "devOptional": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "playwright-core": "1.45.2" }, @@ -14446,8 +13199,9 @@ }, "node_modules/playwright-core": { "version": "1.45.2", - "devOptional": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "bin": { "playwright-core": "cli.js" }, @@ -14457,12 +13211,12 @@ }, "node_modules/playwright/node_modules/fsevents": { "version": "2.3.2", - "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" ], + "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -14667,31 +13421,6 @@ "version": "16.13.1", "license": "MIT" }, - "node_modules/proper-lockfile": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - } - }, - "node_modules/properties-reader": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "mkdirp": "^1.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/steveukx/properties?sponsor=1" - } - }, "node_modules/protobufjs": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.2.tgz", @@ -14715,10 +13444,6 @@ "node": ">=12.0.0" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "license": "MIT" - }, "node_modules/psl": { "version": "1.9.0", "dev": true, @@ -14795,19 +13520,6 @@ ], "license": "MIT" }, - "node_modules/queue-tick": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/randombytes": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/react": { "version": "18.3.1", "license": "MIT", @@ -14837,18 +13549,6 @@ "version": "2.0.2", "license": "MIT" }, - "node_modules/react-toastify": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz", - "integrity": "sha512-mNKt2jBXJg4O7pSdbNUfDdTsK9FIdikfsIE/yUCxbAEXl4HMyJaivrVFcn3Elvt5xvCQYhUZm+hqTIu1UXM3Pw==", - "dependencies": { - "clsx": "^2.1.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - } - }, "node_modules/readable-stream": { "version": "2.3.8", "license": "MIT", @@ -14857,38 +13557,19 @@ "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/isarray": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "license": "MIT" - }, - "node_modules/readdir-glob": { - "version": "1.1.3", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.1.0" - } - }, - "node_modules/readdir-glob/node_modules/minimatch": { - "version": "5.1.6", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, + "node_modules/readable-stream/node_modules/isarray": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" + }, "node_modules/readdirp": { "version": "3.6.0", "devOptional": true, @@ -14903,6 +13584,7 @@ "node_modules/receptor": { "version": "1.0.0", "license": "CC0-1.0", + "peer": true, "dependencies": { "element-closest": "^2.0.1", "keyboardevent-key-polyfill": "^1.0.2", @@ -15041,7 +13723,8 @@ }, "node_modules/resolve-id-refs": { "version": "0.1.0", - "license": "CC0-1.0" + "license": "CC0-1.0", + "peer": true }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", @@ -15072,14 +13755,6 @@ "node": ">=8" } }, - "node_modules/retry": { - "version": "0.12.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/reusify": { "version": "1.0.4", "dev": true, @@ -15323,14 +13998,6 @@ "node": ">=10" } }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/set-function-length": { "version": "1.2.2", "dev": true, @@ -15361,44 +14028,6 @@ "node": ">= 0.4" } }, - "node_modules/sharp": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", - "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", - "hasInstallScript": true, - "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.3", - "semver": "^7.6.3" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.33.5", - "@img/sharp-darwin-x64": "0.33.5", - "@img/sharp-libvips-darwin-arm64": "1.0.4", - "@img/sharp-libvips-darwin-x64": "1.0.4", - "@img/sharp-libvips-linux-arm": "1.0.5", - "@img/sharp-libvips-linux-arm64": "1.0.4", - "@img/sharp-libvips-linux-s390x": "1.0.4", - "@img/sharp-libvips-linux-x64": "1.0.4", - "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", - "@img/sharp-libvips-linuxmusl-x64": "1.0.4", - "@img/sharp-linux-arm": "0.33.5", - "@img/sharp-linux-arm64": "0.33.5", - "@img/sharp-linux-s390x": "0.33.5", - "@img/sharp-linux-x64": "0.33.5", - "@img/sharp-linuxmusl-arm64": "0.33.5", - "@img/sharp-linuxmusl-x64": "0.33.5", - "@img/sharp-wasm32": "0.33.5", - "@img/sharp-win32-ia32": "0.33.5", - "@img/sharp-win32-x64": "0.33.5" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "dev": true, @@ -15455,17 +14084,6 @@ "dev": true, "license": "ISC" }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "license": "MIT" - }, "node_modules/sinon": { "version": "16.1.3", "dev": true, @@ -15560,11 +14178,6 @@ "node": ">=10.0.0" } }, - "node_modules/split-ca": { - "version": "1.0.1", - "dev": true, - "license": "ISC" - }, "node_modules/split2": { "version": "4.2.0", "license": "ISC", @@ -15576,40 +14189,6 @@ "version": "1.0.3", "license": "BSD-3-Clause" }, - "node_modules/ssh-remote-port-forward": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ssh2": "^0.5.48", - "ssh2": "^1.4.0" - } - }, - "node_modules/ssh-remote-port-forward/node_modules/@types/ssh2": { - "version": "0.5.52", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/ssh2-streams": "*" - } - }, - "node_modules/ssh2": { - "version": "1.15.0", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "asn1": "^0.2.6", - "bcrypt-pbkdf": "^1.0.2" - }, - "engines": { - "node": ">=10.16.0" - }, - "optionalDependencies": { - "cpu-features": "~0.0.9", - "nan": "^2.18.0" - } - }, "node_modules/sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", @@ -15654,17 +14233,6 @@ "node": ">=8" } }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/stoppable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", @@ -15691,18 +14259,6 @@ "node": ">=10.0.0" } }, - "node_modules/streamx": { - "version": "2.16.1", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" - } - }, "node_modules/string_decoder": { "version": "1.1.1", "license": "MIT", @@ -15944,51 +14500,6 @@ } } }, - "node_modules/superagent": { - "version": "9.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "component-emitter": "^1.3.0", - "cookiejar": "^2.1.4", - "debug": "^4.3.4", - "fast-safe-stringify": "^2.1.1", - "form-data": "^4.0.0", - "formidable": "^3.5.1", - "methods": "^1.1.2", - "mime": "2.6.0", - "qs": "^6.11.0" - }, - "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/superagent/node_modules/qs": { - "version": "6.12.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/supertest": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "methods": "^1.1.2", - "superagent": "^9.0.1" - }, - "engines": { - "node": ">=14.18.0" - } - }, "node_modules/supports-color": { "version": "7.2.0", "license": "MIT", @@ -16017,7 +14528,8 @@ "node_modules/tabbable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", - "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "peer": true }, "node_modules/tapable": { "version": "2.2.1", @@ -16027,57 +14539,6 @@ "node": ">=6" } }, - "node_modules/tar-fs": { - "version": "3.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^2.1.1", - "bare-path": "^2.1.0" - } - }, - "node_modules/tar-fs/node_modules/tar-stream": { - "version": "3.1.7", - "dev": true, - "license": "MIT", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/tarn": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", @@ -16220,28 +14681,6 @@ "node": "*" } }, - "node_modules/testcontainers": { - "version": "10.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@balena/dockerignore": "^1.0.2", - "@types/dockerode": "^3.3.24", - "archiver": "^5.3.2", - "async-lock": "^1.4.1", - "byline": "^5.0.0", - "debug": "^4.3.4", - "docker-compose": "^0.24.6", - "dockerode": "^3.3.5", - "get-port": "^5.1.1", - "node-fetch": "^2.7.0", - "proper-lockfile": "^4.1.2", - "properties-reader": "^2.3.0", - "ssh-remote-port-forward": "^1.0.4", - "tar-fs": "^3.0.5", - "tmp": "^0.2.1" - } - }, "node_modules/text-table": { "version": "0.2.0", "dev": true, @@ -16996,11 +15435,6 @@ "node": ">=0.10.0" } }, - "node_modules/workerpool": { - "version": "6.5.1", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/wrap-ansi": { "version": "8.1.0", "dev": true, @@ -17167,17 +15601,6 @@ "dev": true, "license": "ISC" }, - "node_modules/yaml": { - "version": "2.4.2", - "dev": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/yargs": { "version": "17.7.2", "license": "MIT", @@ -17201,31 +15624,6 @@ "node": ">=12" } }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", @@ -17247,91 +15645,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/zip-stream": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "archiver-utils": "^3.0.4", - "compress-commons": "^4.1.2", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/zip-stream/node_modules/archiver-utils": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "^7.2.3", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/zip-stream/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/zip-stream/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/zip-stream/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/zip-stream/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "packages/shared-resources": { "name": "@repo/ui", "version": "1.0.0", @@ -17381,4 +15694,4 @@ } } } -} \ No newline at end of file +}