typescript fixin
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 14s
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 14s
This commit is contained in:
18
App.tsx
18
App.tsx
@@ -4,6 +4,7 @@ import { FlyerDisplay } from './components/FlyerDisplay';
|
||||
import { ExtractedDataTable } from './components/ExtractedDataTable';
|
||||
import { AnalysisPanel } from './components/AnalysisPanel';
|
||||
import { PriceChart } from './components/PriceChart';
|
||||
import * as pdfjsLib from 'pdfjs-dist';
|
||||
import { ErrorDisplay } from './components/ErrorDisplay';
|
||||
import { Header } from './components/Header';
|
||||
import { logger } from './services/logger';
|
||||
@@ -35,9 +36,8 @@ type AuthStatus = 'SIGNED_OUT' | 'ANONYMOUS' | 'AUTHENTICATED';
|
||||
// pdf.js worker configuration
|
||||
// This is crucial for allowing pdf.js to process PDFs in a separate thread, preventing the UI from freezing.
|
||||
// We need to explicitly tell pdf.js where to load its worker script from.
|
||||
// Since we're using a CDN for the main library, we'll use the same CDN for the worker.
|
||||
// @ts-ignore - pdfjsLib is globally available from the script tag in index.html
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjsLib.version}/pdf.worker.mjs`;
|
||||
// By importing pdfjs-dist, we can host the worker locally, which is more reliable.
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.mjs', import.meta.url).toString();
|
||||
|
||||
function App() {
|
||||
const [flyers, setFlyers] = useState<Flyer[]>([]);
|
||||
@@ -107,6 +107,18 @@ function App() {
|
||||
}
|
||||
}, [profile]);
|
||||
|
||||
// Effect to mark the app as "ready" for data fetching.
|
||||
// This replaces the onReady callback from the now-removed SystemCheck component.
|
||||
useEffect(() => {
|
||||
if (!isDbConnected) {
|
||||
setIsReady(true);
|
||||
} else {
|
||||
// A short delay to allow other components to initialize.
|
||||
const timer = setTimeout(() => setIsReady(true), 250);
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
}, [isDbConnected]);
|
||||
|
||||
// This is the login handler that will be passed to the LoginPage component.
|
||||
const handleLogin = async (email: string, pass: string) => {
|
||||
if (!supabase) return;
|
||||
|
||||
@@ -3,8 +3,10 @@ import { FlyerDisplay } from './FlyerDisplay';
|
||||
import { ExtractedDataTable } from './ExtractedDataTable';
|
||||
import { AnalysisPanel } from './AnalysisPanel';
|
||||
import { PriceChart } from './PriceChart';
|
||||
import * as pdfjsLib from 'pdfjs-dist';
|
||||
import { ErrorDisplay } from './ErrorDisplay';
|
||||
import { Header } from './Header';
|
||||
import { logger } from '../services/logger';
|
||||
import { isImageAFlyer, extractCoreDataFromImage, extractAddressFromImage, extractLogoFromImage } from '../services/geminiService';
|
||||
import type { FlyerItem, Flyer, MasterGroceryItem, DealItem, ProcessingStage, StageStatus, Store, Profile, ShoppingList, ShoppingListItem } from '../types';
|
||||
import type { Database } from '../types/supabase'; // Correctly import the Database type
|
||||
@@ -130,8 +132,9 @@ function App() {
|
||||
try {
|
||||
const allFlyers = await getFlyers();
|
||||
setFlyers(allFlyers);
|
||||
} catch(e: any) {
|
||||
setError(e.message);
|
||||
} catch(e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(errorMessage);
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -143,8 +146,9 @@ function App() {
|
||||
try {
|
||||
const items = await getWatchedItems(userId);
|
||||
setWatchedItems(items);
|
||||
} catch (e: any) {
|
||||
setError(`Could not fetch watched items: ${e.message}`);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(`Could not fetch watched items: ${errorMessage}`);
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -162,8 +166,9 @@ function App() {
|
||||
} else if (lists.length === 0) {
|
||||
setActiveListId(null);
|
||||
}
|
||||
} catch (e: any) {
|
||||
setError(`Could not fetch shopping lists: ${e.message}`);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(`Could not fetch shopping lists: ${errorMessage}`);
|
||||
}
|
||||
}, [activeListId]);
|
||||
|
||||
@@ -172,8 +177,9 @@ function App() {
|
||||
try {
|
||||
const items = await getAllMasterItems();
|
||||
setMasterItems(items);
|
||||
} catch (e: any) {
|
||||
setError(`Could not fetch master item list: ${e.message}`);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(`Could not fetch master item list: ${errorMessage}`);
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -243,8 +249,9 @@ function App() {
|
||||
try {
|
||||
const items = await getFlyerItems(flyer.id);
|
||||
setFlyerItems(items);
|
||||
} catch (e: any) {
|
||||
setError(e.message);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(errorMessage);
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -305,8 +312,9 @@ function App() {
|
||||
}));
|
||||
|
||||
setActiveDeals(deals);
|
||||
} catch (e: any) {
|
||||
setError(`Could not fetch active deals: ${e.message}`);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(`Could not fetch active deals: ${errorMessage}`);
|
||||
} finally {
|
||||
setActiveDealsLoading(false);
|
||||
}
|
||||
@@ -346,8 +354,9 @@ function App() {
|
||||
const validFlyerIds = validFlyers.map(f => f.id);
|
||||
const totalCount = await countFlyerItemsForFlyers(validFlyerIds);
|
||||
setTotalActiveItems(totalCount);
|
||||
} catch (e: any) {
|
||||
console.error("Failed to calculate total active items:", e.message);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
logger.error("Failed to calculate total active items:", { error: errorMessage });
|
||||
setTotalActiveItems(0);
|
||||
}
|
||||
};
|
||||
@@ -416,8 +425,9 @@ function App() {
|
||||
updateStage?.(stageIndex, { status: 'in-progress' });
|
||||
storeAddress = await withTimeout(extractAddressFromImage(files[0]), nonCriticalTimeout);
|
||||
updateStage?.(stageIndex++, { status: 'completed' }); // stageIndex is now 4
|
||||
} catch (e: any) {
|
||||
console.warn("Non-critical step failed: Address extraction.", e.message);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
logger.warn("Non-critical step failed: Address extraction.", { error: errorMessage });
|
||||
updateStage?.(stageIndex++, { status: 'error', detail: '(Skipped)' }); // stageIndex is now 4
|
||||
}
|
||||
|
||||
@@ -428,8 +438,9 @@ function App() {
|
||||
const logoData = await withTimeout(extractLogoFromImage(files.slice(0, 1)), nonCriticalTimeout);
|
||||
storeLogoBase64 = logoData.store_logo_base_64;
|
||||
updateStage?.(stageIndex++, { status: 'completed' }); // stageIndex is now 5
|
||||
} catch (e: any) {
|
||||
console.warn("Non-critical step failed: Logo extraction.", e.message);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
logger.warn("Non-critical step failed: Logo extraction.", { error: errorMessage });
|
||||
updateStage?.(stageIndex++, { status: 'error', detail: '(Skipped)' }); // stageIndex is now 5
|
||||
}
|
||||
|
||||
@@ -607,8 +618,9 @@ function App() {
|
||||
}
|
||||
return prevItems; // Item already existed in list
|
||||
});
|
||||
} catch (e: any) {
|
||||
setError(`Could not add watched item: ${e.message}`);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(`Could not add watched item: ${errorMessage}`);
|
||||
await fetchWatchedItems(session?.user?.id);
|
||||
}
|
||||
}, [session, fetchWatchedItems]);
|
||||
@@ -618,8 +630,9 @@ function App() {
|
||||
try {
|
||||
await removeWatchedItem(session.user.id, masterItemId);
|
||||
setWatchedItems(prevItems => prevItems.filter(item => item.id !== masterItemId));
|
||||
} catch (e: any) {
|
||||
setError(`Could not remove watched item: ${e.message}`);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(`Could not remove watched item: ${errorMessage}`);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
@@ -630,8 +643,9 @@ function App() {
|
||||
const newList = await createShoppingList(session.user.id, name);
|
||||
setShoppingLists(prev => [...prev, newList]);
|
||||
setActiveListId(newList.id);
|
||||
} catch (e: any) {
|
||||
setError(`Could not create list: ${e.message}`);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(`Could not create list: ${errorMessage}`);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
@@ -644,8 +658,9 @@ function App() {
|
||||
if (activeListId === listId) {
|
||||
setActiveListId(newLists.length > 0 ? newLists[0].id : null);
|
||||
}
|
||||
} catch (e: any) {
|
||||
setError(`Could not delete list: ${e.message}`);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(`Could not delete list: ${errorMessage}`);
|
||||
}
|
||||
}, [session, shoppingLists, activeListId]);
|
||||
|
||||
@@ -662,8 +677,9 @@ function App() {
|
||||
}
|
||||
return list;
|
||||
}));
|
||||
} catch (e: any) {
|
||||
setError(`Could not add item to list: ${e.message}`);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(`Could not add item to list: ${errorMessage}`);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
@@ -677,8 +693,9 @@ function App() {
|
||||
}
|
||||
return list;
|
||||
}));
|
||||
} catch (e: any) {
|
||||
setError(`Could not update list item: ${e.message}`);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(`Could not update list item: ${errorMessage}`);
|
||||
}
|
||||
}, [session, activeListId]);
|
||||
|
||||
@@ -692,8 +709,9 @@ function App() {
|
||||
}
|
||||
return list;
|
||||
}));
|
||||
} catch (e: any) {
|
||||
setError(`Could not remove list item: ${e.message}`);
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
setError(`Could not remove list item: ${errorMessage}`);
|
||||
}
|
||||
}, [session, activeListId]);
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ export const SystemCheck: React.FC<SystemCheckProps> = ({ onReady }) => {
|
||||
for (const key in results) {
|
||||
// Ensure the property belongs to the object itself.
|
||||
if (Object.prototype.hasOwnProperty.call(results, key)) {
|
||||
const { pass, message } = (results as any)[key];
|
||||
const { pass, message } = (results as Record<string, { pass: boolean; message: string; }>)[key];
|
||||
updateCheckStatus(key, pass ? 'pass' : 'fail', message);
|
||||
if (!pass) {
|
||||
allTestsPassed = false;
|
||||
|
||||
198
package-lock.json
generated
198
package-lock.json
generated
@@ -10,6 +10,7 @@
|
||||
"dependencies": {
|
||||
"@google/genai": "^1.29.0",
|
||||
"@supabase/supabase-js": "^2.81.1",
|
||||
"pdfjs-dist": "^5.4.394",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-router-dom": "^7.9.5",
|
||||
@@ -1341,6 +1342,191 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas": {
|
||||
"version": "0.1.82",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.82.tgz",
|
||||
"integrity": "sha512-FGjyUBoF0sl1EenSiE4UV2WYu76q6F9GSYedq5EiOCOyGYoQ/Owulcv6rd7v/tWOpljDDtefXXIaOCJrVKem4w==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"workspaces": [
|
||||
"e2e/*"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@napi-rs/canvas-android-arm64": "0.1.82",
|
||||
"@napi-rs/canvas-darwin-arm64": "0.1.82",
|
||||
"@napi-rs/canvas-darwin-x64": "0.1.82",
|
||||
"@napi-rs/canvas-linux-arm-gnueabihf": "0.1.82",
|
||||
"@napi-rs/canvas-linux-arm64-gnu": "0.1.82",
|
||||
"@napi-rs/canvas-linux-arm64-musl": "0.1.82",
|
||||
"@napi-rs/canvas-linux-riscv64-gnu": "0.1.82",
|
||||
"@napi-rs/canvas-linux-x64-gnu": "0.1.82",
|
||||
"@napi-rs/canvas-linux-x64-musl": "0.1.82",
|
||||
"@napi-rs/canvas-win32-x64-msvc": "0.1.82"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-android-arm64": {
|
||||
"version": "0.1.82",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.82.tgz",
|
||||
"integrity": "sha512-bvZhN0iI54ouaQOrgJV96H2q7J3ZoufnHf4E1fUaERwW29Rz4rgicohnAg4venwBJZYjGl5Yl3CGmlAl1LZowQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-darwin-arm64": {
|
||||
"version": "0.1.82",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.82.tgz",
|
||||
"integrity": "sha512-InuBHKCyuFqhNwNr4gpqazo5Xp6ltKflqOLiROn4hqAS8u21xAHyYCJRgHwd+a5NKmutFTaRWeUIT/vxWbU/iw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-darwin-x64": {
|
||||
"version": "0.1.82",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.82.tgz",
|
||||
"integrity": "sha512-aQGV5Ynn96onSXcuvYb2y7TRXD/t4CL2EGmnGqvLyeJX1JLSNisKQlWN/1bPDDXymZYSdUqbXehj5qzBlOx+RQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-arm-gnueabihf": {
|
||||
"version": "0.1.82",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.82.tgz",
|
||||
"integrity": "sha512-YIUpmHWeHGGRhWitT1KJkgj/JPXPfc9ox8oUoyaGPxolLGPp5AxJkq8wIg8CdFGtutget968dtwmx71m8o3h5g==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-arm64-gnu": {
|
||||
"version": "0.1.82",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.82.tgz",
|
||||
"integrity": "sha512-AwLzwLBgmvk7kWeUgItOUor/QyG31xqtD26w1tLpf4yE0hiXTGp23yc669aawjB6FzgIkjh1NKaNS52B7/qEBQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-arm64-musl": {
|
||||
"version": "0.1.82",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.82.tgz",
|
||||
"integrity": "sha512-moZWuqepAwWBffdF4JDadt8TgBD02iMhG6I1FHZf8xO20AsIp9rB+p0B8Zma2h2vAF/YMjeFCDmW5un6+zZz9g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-riscv64-gnu": {
|
||||
"version": "0.1.82",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.82.tgz",
|
||||
"integrity": "sha512-w9++2df2kG9eC9LWYIHIlMLuhIrKGQYfUxs97CwgxYjITeFakIRazI9LYWgVzEc98QZ9x9GQvlicFsrROV59MQ==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-x64-gnu": {
|
||||
"version": "0.1.82",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.82.tgz",
|
||||
"integrity": "sha512-lZulOPwrRi6hEg/17CaqdwWEUfOlIJuhXxincx1aVzsVOCmyHf+xFq4i6liJl1P+x2v6Iz2Z/H5zHvXJCC7Bwg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-x64-musl": {
|
||||
"version": "0.1.82",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.82.tgz",
|
||||
"integrity": "sha512-Be9Wf5RTv1w6GXlTph55K3PH3vsAh1Ax4T1FQY1UYM0QfD0yrwGdnJ8/fhqw7dEgMjd59zIbjJQC8C3msbGn5g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-win32-x64-msvc": {
|
||||
"version": "0.1.82",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.82.tgz",
|
||||
"integrity": "sha512-LN/i8VrvxTDmEEK1c10z2cdOTkWT76LlTGtyZe5Kr1sqoSomKeExAjbilnu1+oee5lZUgS5yfZ2LNlVhCeARuw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@@ -6157,6 +6343,18 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pdfjs-dist": {
|
||||
"version": "5.4.394",
|
||||
"resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-5.4.394.tgz",
|
||||
"integrity": "sha512-9ariAYGqUJzx+V/1W4jHyiyCep6IZALmDzoaTLZ6VNu8q9LWi1/ukhzHgE2Xsx96AZi0mbZuK4/ttIbqSbLypg==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=20.16.0 || >=22.3.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@napi-rs/canvas": "^0.1.81"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"dependencies": {
|
||||
"@google/genai": "^1.29.0",
|
||||
"@supabase/supabase-js": "^2.81.1",
|
||||
"pdfjs-dist": "^5.4.394",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-router-dom": "^7.9.5",
|
||||
@@ -20,16 +21,16 @@
|
||||
"supabase": "^2.58.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@types/node": "^24.10.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.46.4",
|
||||
"@typescript-eslint/parser": "^8.46.4",
|
||||
"@vitejs/plugin-react": "^5.1.0",
|
||||
"@vitest/coverage-v8": "^4.0.8",
|
||||
"autoprefixer": "^10.4.22",
|
||||
"eslint-plugin-react": "^7.35.0",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-plugin-react": "^7.35.0",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.4.24",
|
||||
"globals": "^15.9.0",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// vitest.setup.ts
|
||||
import { expect } from 'vitest';
|
||||
import '@testing-library/jest-dom/vitest';
|
||||
|
||||
// You can add any other global setup here if needed.
|
||||
Reference in New Issue
Block a user