Bump langsmith to 0.5.20 and override @langchain/classic to fix CVE

langsmith <=0.5.18 leaks streamed LLM output past redaction controls
(GHSA-rr7j-v2q5-chgv). The transitive pin via @n8n/ai-utilities held
@langchain/classic at 1.0.5 which required langsmith ^0.3.64, blocking
the upgrade. Add npm overrides for @langchain/classic (^1.0.27) and
langsmith (^0.5.19) to resolve all three langsmith advisories.

The lockfile refresh bumps eslint-plugin-react-hooks from 7.0.1 to
7.1.0 which enables the react-hooks/refs and set-state-in-effect
rules. Fix the resulting lint errors:

- PDFPreview (console + trust): read currentPage through a ref synced
  via useEffect, keeping the setState updater pure and ref access
  outside of render
- MeasuresPage: remove redundant categoryFilter state that mirrored
  urlCategory, use a ref to detect URL changes and trigger refetch
  as the single source of category refetches
- WebhooksSettingsPage: defer loadEvents via requestAnimationFrame
  to avoid synchronous setState within the effect body

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-04-17 15:08:13 +02:00
parent e1148f812e
commit 8ce429507b
6 changed files with 287 additions and 261 deletions

View File

@@ -21,7 +21,7 @@ import {
Spinner,
} from "@probo/ui";
import { IconMinusLarge } from "@probo/ui/src/Atoms/Icons/IconMinusLarge";
import { type ComponentProps, useRef, useState } from "react";
import { type ComponentProps, useCallback, useEffect, useRef, useState } from "react";
import { Document, Page, pdfjs } from "react-pdf";
import "react-pdf/dist/Page/TextLayer.css";
@@ -51,11 +51,17 @@ export function PDFPreview({ src, name }: { src: string; name?: string }) {
setScale(scale * factor);
};
const movePage = (direction: 1 | -1) => () => {
if (currentPage === 1 && direction === -1) {
const currentPageRef = useRef(currentPage);
useEffect(() => {
currentPageRef.current = currentPage;
}, [currentPage]);
const movePage = useCallback((direction: 1 | -1) => {
const prev = currentPageRef.current;
if (prev === 1 && direction === -1) {
return;
}
const newPage = currentPage + direction;
const newPage = prev + direction;
const page = documentRef.current?.pages.current[newPage - 1];
if (!page) {
return;
@@ -66,9 +72,9 @@ export function PDFPreview({ src, name }: { src: string; name?: string }) {
inline: "center",
});
setCurrentPage(newPage);
};
}, []);
const resolveCurrentPage = () => {
const resolveCurrentPage = useCallback(() => {
if (!wrapperRef.current) {
return;
}
@@ -81,10 +87,11 @@ export function PDFPreview({ src, name }: { src: string; name?: string }) {
for (let i = 0; i < pages.length; i++) {
const childRect = pages[i].getBoundingClientRect();
if (childRect.top <= parentMiddleY && childRect.bottom >= parentMiddleY) {
return setCurrentPage(i + 1);
setCurrentPage(i + 1);
return;
}
}
};
}, []);
const handleDownload = () => {
const link = document.createElement("a");
@@ -100,7 +107,7 @@ export function PDFPreview({ src, name }: { src: string; name?: string }) {
<div>{name}</div>
<div className="mx-auto flex gap-1 items-center">
<button
onClick={movePage(-1)}
onClick={() => movePage(-1)}
className={btnClass}
disabled={currentPage === 1}
>
@@ -112,7 +119,7 @@ export function PDFPreview({ src, name }: { src: string; name?: string }) {
/
{numPages}
</div>
<button onClick={movePage(1)} className={btnClass}>
<button onClick={() => movePage(1)} className={btnClass}>
<IconChevronRight size={16} />
</button>
</div>