From 1b7e7f53366725192c131a91cf4de0220601d596 Mon Sep 17 00:00:00 2001 From: Omkar Phansopkar Date: Wed, 19 Apr 2023 18:02:52 +0530 Subject: [PATCH] Fixed window not found & occasional sqlite error for packages Signed-off-by: Omkar Phansopkar --- src/components/DropZone/DropZone.tsx | 56 +++-- src/contexts/workbenchContext.tsx | 27 ++- src/mainActions.ts | 203 ++++++++++-------- src/pages/Home/Home.tsx | 138 +++++++----- src/pages/PackageInfoDash/PackageInfoDash.tsx | 167 +++++++------- src/services/models/packages.ts | 113 +++++----- src/services/workbenchDB.ts | 36 +++- 7 files changed, 410 insertions(+), 330 deletions(-) diff --git a/src/components/DropZone/DropZone.tsx b/src/components/DropZone/DropZone.tsx index 5ddcd462..b0f7bcb7 100644 --- a/src/components/DropZone/DropZone.tsx +++ b/src/components/DropZone/DropZone.tsx @@ -1,62 +1,60 @@ -import { toast } from 'react-toastify'; -import React, { DragEvent } from 'react' -import { useNavigate } from 'react-router-dom'; +import { toast } from "react-toastify"; +import React, { DragEvent } from "react"; +import { useNavigate } from "react-router-dom"; -import { useWorkbenchDB } from '../../contexts/workbenchContext'; -import { ROUTES } from '../../constants/routes'; +import { useWorkbenchDB } from "../../contexts/workbenchContext"; +import { ROUTES } from "../../constants/routes"; - -const lastLogs:{ [key: string]: number} = {} +const lastLogs: { [key: string]: number } = {}; export const CustomLogger = (id: string, ...args: unknown[]) => { - const currentTime = (new Date()).getTime(); - if(!(lastLogs[id] && currentTime < lastLogs[id]+1000)){ + const currentTime = new Date().getTime(); + if (!(lastLogs[id] && currentTime < lastLogs[id] + 1000)) { console.log(id, ...args); lastLogs[id] = currentTime; } -} +}; const DropZone = (props: React.PropsWithChildren) => { const navigate = useNavigate(); const { sqliteParser, importJsonFile } = useWorkbenchDB(); - function DragOverHandler(e: DragEvent){ + function DragOverHandler(e: DragEvent) { e.preventDefault(); e.stopPropagation(); // CustomLogger("Drag detected", e, e.dataTransfer.files); } - function DropHandler(e: DragEvent){ + function DropHandler(e: DragEvent) { e.preventDefault(); e.stopPropagation(); const regex = { json: /\.(json)+$/i, sqlite: /\.(sqlite)+$/i, - } + }; - const validFiles = - Array.from(e.dataTransfer.files) - .filter(file => file.name.match(regex.json) || file.name.match(regex.sqlite)) - .filter(file => file !== null); + const validFiles = Array.from(e.dataTransfer.files) + .filter( + (file) => file.name.match(regex.json) || file.name.match(regex.sqlite) + ) + .filter((file) => file !== null); const fileToImport = validFiles[0]; - + console.log("Dropped files:", e, e.dataTransfer.files); console.log("Valid files:", validFiles); - if(!validFiles.length){ - return toast('Only json/sqlite file can be imported !', { - type: 'error', + if (!validFiles.length) { + return toast.error("Only json/sqlite file can be imported !", { style: { width: 320 }, }); } - if(validFiles.length > 1){ - toast(`Only 1 json/sqlite file will be imported at a time`, { - type: 'warning', + if (validFiles.length > 1) { + toast.warn(`Only 1 json/sqlite file can be imported at a time`, { style: { width: 375 }, }); } - if(regex.sqlite.test(fileToImport.name)){ + if (regex.sqlite.test(fileToImport.name)) { console.log("Parsing sqlite file:", fileToImport.name); sqliteParser(fileToImport.path); navigate(ROUTES.HOME); @@ -69,9 +67,9 @@ const DropZone = (props: React.PropsWithChildren) => { return (
- { props.children } + {props.children}
- ) -} + ); +}; -export default DropZone \ No newline at end of file +export default DropZone; \ No newline at end of file diff --git a/src/contexts/workbenchContext.tsx b/src/contexts/workbenchContext.tsx index 6158158a..73e50f3f 100644 --- a/src/contexts/workbenchContext.tsx +++ b/src/contexts/workbenchContext.tsx @@ -220,9 +220,7 @@ export const WorkbenchDBProvider = (props: React.PropsWithChildren { + abortImport(); + console.error("Some error parsing data (caught in workbenchContext) !!", err); + toast.error( + "Some error parsing data !! \nPlease check console for more info" + ); }); } @@ -330,9 +333,7 @@ export const WorkbenchDBProvider = (props: React.PropsWithChildren { @@ -341,14 +342,12 @@ export const WorkbenchDBProvider = (props: React.PropsWithChildren { if(!value.db || !value.initialized){ - return toast("No JSON/Sqlite imported to save as new SQLite file", { + return toast.error("No JSON/Sqlite imported to save as new SQLite file", { type: "error", style: { width: 400 }, }); @@ -365,7 +364,7 @@ export const WorkbenchDBProvider = (props: React.PropsWithChildren { console.log("Saved", newFileName); - toast("Saved sqlite file, loading from new file", { type: 'success' }); + toast.success("Saved sqlite file, loading from new file"); sqliteParser(newFileName, true); }); } diff --git a/src/mainActions.ts b/src/mainActions.ts index fb2bf124..ea094c75 100644 --- a/src/mainActions.ts +++ b/src/mainActions.ts @@ -1,63 +1,75 @@ -import * as electronOs from "os" -import { ipcMain, dialog, BrowserWindow } from 'electron'; +import * as electronOs from "os"; +import { ipcMain, dialog, BrowserWindow } from "electron"; import { ErrorInfo, OPEN_DIALOG_CHANNEL, OPEN_ERROR_DIALOG_CHANNEL, IMPORT_REPLY_CHANNEL, - SAVE_REPLY_CHANNEL, + SAVE_REPLY_CHANNEL, JSON_IMPORT_REPLY_FORMAT, SQLITE_IMPORT_REPLY_FORMAT, SQLITE_SAVE_REPLY_FORMAT, SQLITE_PATH_FOR_JSON_REQUEST_FORMAT, UTIL_CHANNEL, -} from './constants/IpcConnection'; +} from "./constants/IpcConnection"; -export function chooseSqlitePathForJsonImport(mainWindow: BrowserWindow, jsonFilePath: string){ +export function chooseSqlitePathForJsonImport( + mainWindow: BrowserWindow, + jsonFilePath: string +) { console.log("Prompt to choose Sqlite path for JSON file"); let defaultPath; - if (electronOs.platform() === 'linux') { + if (electronOs.platform() === "linux") { // remove the .json (or other) extention of the path. - defaultPath = jsonFilePath.substring(0, jsonFilePath.lastIndexOf('.')) + '.sqlite'; + defaultPath = + jsonFilePath.substring(0, jsonFilePath.lastIndexOf(".")) + ".sqlite"; } else { // FIXME: this is some ugly regex used to get filename with no extension. // see: https://stackoverflow.com/questions/4250364/how-to-trim-a-file-extension-from-a-string-in-javascript - defaultPath = jsonFilePath.replace(/^.*[\\/]/, '').replace(/\.[^/.]+$/, ''); + defaultPath = jsonFilePath.replace(/^.*[\\/]/, "").replace(/\.[^/.]+$/, ""); } // Immediately ask for a path to create & save the SQLite database - dialog.showSaveDialog(mainWindow, { - title: 'Save a SQLite Database File', - defaultPath: defaultPath, - filters: [{ - name: 'SQLite File', - extensions: ['sqlite'] - }] - }).then((sqliteFile) => { - const sqliteFilePath = sqliteFile.filePath; - if (sqliteFilePath === undefined) { - console.log("Sqlite file path isn't valid:", sqliteFilePath); - return; - } - const reply: JSON_IMPORT_REPLY_FORMAT = { - jsonFilePath, - sqliteFilePath - } - mainWindow.webContents.send(IMPORT_REPLY_CHANNEL.JSON, reply); - }); + dialog + .showSaveDialog(mainWindow, { + title: "Save a SQLite Database File", + defaultPath: defaultPath, + filters: [ + { + name: "SQLite File", + extensions: ["sqlite"], + }, + ], + }) + .then((sqliteFile) => { + const sqliteFilePath = sqliteFile.filePath; + if (sqliteFilePath === undefined) { + console.log("Sqlite file path isn't valid:", sqliteFilePath); + return; + } + const reply: JSON_IMPORT_REPLY_FORMAT = { + jsonFilePath, + sqliteFilePath, + }; + mainWindow.webContents.send(IMPORT_REPLY_CHANNEL.JSON, reply); + }); } -export function importJsonFile(mainWindow: BrowserWindow){ +export function importJsonFile(mainWindow: BrowserWindow) { console.log("Prompt to Import JSON file"); - dialog.showOpenDialog(mainWindow, { - title: 'Open a JSON File', - filters: [{ - name: 'JSON File', - extensions: ['json'] - }] - }).then(({filePaths}) => { + dialog + .showOpenDialog(mainWindow, { + title: "Open a JSON File", + filters: [ + { + name: "JSON File", + extensions: ["json"], + }, + ], + }) + .then(({ filePaths }) => { if (filePaths === undefined || !filePaths[0]) { return; } @@ -65,59 +77,60 @@ export function importJsonFile(mainWindow: BrowserWindow){ }); } -export function openSqliteFile(mainWindow: BrowserWindow){ +export function openSqliteFile(mainWindow: BrowserWindow) { console.log("Prompt to open SQLite file"); - dialog.showOpenDialog(mainWindow, { - properties: ['openFile'], - title: 'Open a SQLite File', - filters: [{ - name: 'SQLite File', - extensions: ['sqlite'] - }] - }).then(({ filePaths }) => { - if (filePaths && filePaths[0]) { - const sqliteFilePath = filePaths[0] - const reply: SQLITE_IMPORT_REPLY_FORMAT = { sqliteFilePath }; - mainWindow.webContents.send(IMPORT_REPLY_CHANNEL.SQLITE, reply); - } else { - console.log("Sqlite file path isn't valid:", filePaths); - return; - } - }); + dialog + .showOpenDialog(mainWindow, { + properties: ["openFile"], + title: "Open a SQLite File", + filters: [ + { + name: "SQLite File", + extensions: ["sqlite"], + }, + ], + }) + .then(({ filePaths }) => { + if (filePaths && filePaths[0]) { + const sqliteFilePath = filePaths[0]; + const reply: SQLITE_IMPORT_REPLY_FORMAT = { sqliteFilePath }; + mainWindow.webContents.send(IMPORT_REPLY_CHANNEL.SQLITE, reply); + } else { + console.log("Sqlite file path isn't valid:", filePaths); + return; + } + }); } -export function saveSqliteFile(mainWindow: BrowserWindow){ +export function saveSqliteFile(mainWindow: BrowserWindow) { console.log("Save sqlite file prompt"); - dialog.showSaveDialog(mainWindow, { - title: 'Save as a Database File', - defaultPath: 'fileName.sqlite', - filters: [ - { name: 'SQLite File', extensions: ['sqlite'] } - ] - }).then((file) => { - const sqliteFilePath = file?.filePath; - if (sqliteFilePath) { - const reply: SQLITE_SAVE_REPLY_FORMAT = { sqliteFilePath }; - mainWindow.webContents.send(SAVE_REPLY_CHANNEL.SQLITE, reply); - } else { - console.log("Sqlite file path isn't valid:", file, sqliteFilePath); - return; - } - }); + dialog + .showSaveDialog(mainWindow, { + title: "Save as a Database File", + defaultPath: "fileName.sqlite", + filters: [{ name: "SQLite File", extensions: ["sqlite"] }], + }) + .then((file) => { + const sqliteFilePath = file?.filePath; + if (sqliteFilePath) { + const reply: SQLITE_SAVE_REPLY_FORMAT = { sqliteFilePath }; + mainWindow.webContents.send(SAVE_REPLY_CHANNEL.SQLITE, reply); + } else { + console.log("Sqlite file path isn't valid:", file, sqliteFilePath); + return; + } + }); } -export function showErrorDialog(err: ErrorInfo){ - console.log("Showing error to user:", err) - dialog.showErrorBox( - err.title, - err.message - ); +export function showErrorDialog(err: ErrorInfo) { + console.log("Showing error to user:", err); + dialog.showErrorBox(err.title, err.message); } -export function setCurrentFileTitle(mainWindow: BrowserWindow, title: string){ - if(!mainWindow){ +export function setCurrentFileTitle(mainWindow: BrowserWindow, title: string) { + if (!mainWindow) { console.log("Main window not found:", title, mainWindow); return; } @@ -125,20 +138,32 @@ export function setCurrentFileTitle(mainWindow: BrowserWindow, title: string){ mainWindow.setTitle(titleString); } -export function setUpGlobalIpcListeners(){ - const getCurrentWindow = () => BrowserWindow.getFocusedWindow(); - ipcMain.on(OPEN_DIALOG_CHANNEL.JSON, () => importJsonFile(getCurrentWindow())); +export function setUpGlobalIpcListeners() { + const getSenderWindow = (e: Electron.IpcMainEvent) => { + return BrowserWindow.fromId(e.sender.id); + }; + ipcMain.on(OPEN_DIALOG_CHANNEL.JSON, (e) => + importJsonFile(getSenderWindow(e)) + ); ipcMain.on( OPEN_DIALOG_CHANNEL.SQLITE_PATH_FOR_JSON, - (_, message: SQLITE_PATH_FOR_JSON_REQUEST_FORMAT) => - chooseSqlitePathForJsonImport(getCurrentWindow(), message.jsonFilePath) + (e, message: SQLITE_PATH_FOR_JSON_REQUEST_FORMAT) => + chooseSqlitePathForJsonImport(getSenderWindow(e), message.jsonFilePath) + ); + ipcMain.on(OPEN_DIALOG_CHANNEL.SQLITE, (e) => + openSqliteFile(getSenderWindow(e)) + ); + ipcMain.on(OPEN_DIALOG_CHANNEL.SAVE_SQLITE, (e) => + saveSqliteFile(getSenderWindow(e)) + ); + ipcMain.on(UTIL_CHANNEL.SET_CURRENT_FILE_TITLE, (e, title: string) => + setCurrentFileTitle(getSenderWindow(e), title) + ); + ipcMain.on(OPEN_ERROR_DIALOG_CHANNEL, (_, err: ErrorInfo) => + showErrorDialog(err) ); - ipcMain.on(OPEN_DIALOG_CHANNEL.SQLITE, () => openSqliteFile(getCurrentWindow())); - ipcMain.on(OPEN_DIALOG_CHANNEL.SAVE_SQLITE, () => saveSqliteFile(getCurrentWindow())); - ipcMain.on(UTIL_CHANNEL.SET_CURRENT_FILE_TITLE, (_, title: string) => setCurrentFileTitle(getCurrentWindow(), title)); - ipcMain.on(OPEN_ERROR_DIALOG_CHANNEL, (_, err: ErrorInfo) => showErrorDialog(err)); } -export function setUpWindowListeners(mainWindow: BrowserWindow){ - mainWindow.on('ready-to-show', () => setCurrentFileTitle(mainWindow, "")); +export function setUpWindowListeners(mainWindow: BrowserWindow) { + mainWindow.on("ready-to-show", () => setCurrentFileTitle(mainWindow, "")); } \ No newline at end of file diff --git a/src/pages/Home/Home.tsx b/src/pages/Home/Home.tsx index b87add14..e5291580 100644 --- a/src/pages/Home/Home.tsx +++ b/src/pages/Home/Home.tsx @@ -1,21 +1,32 @@ -import moment from 'moment' -import electron from 'electron' -import * as electronFs from "fs" -import { toast } from 'react-toastify' -import { useNavigate } from 'react-router-dom' -import React, { useMemo, useState } from 'react' - -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faCogs, faDatabase, faFileCode, faFloppyDisk, faFolder, faTrash } from '@fortawesome/free-solid-svg-icons' - -import { useWorkbenchDB } from '../../contexts/workbenchContext' -import CoreButton from '../../components/CoreButton/CoreButton'; -import ProgressLoader from '../../components/ProgressLoader/ProgressLoader' - -import { OPEN_DIALOG_CHANNEL } from '../../constants/IpcConnection'; -import { GetHistory, HistoryItem, RemoveEntry } from '../../services/historyStore' - -import './home.css' +import moment from "moment"; +import electron from "electron"; +import * as electronFs from "fs"; +import { toast } from "react-toastify"; +import { useNavigate } from "react-router-dom"; +import React, { useMemo, useState } from "react"; + +import { + faCogs, + faDatabase, + faFileCode, + faFloppyDisk, + faFolder, + faTrash, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; + +import { useWorkbenchDB } from "../../contexts/workbenchContext"; +import CoreButton from "../../components/CoreButton/CoreButton"; +import ProgressLoader from "../../components/ProgressLoader/ProgressLoader"; + +import { OPEN_DIALOG_CHANNEL } from "../../constants/IpcConnection"; +import { + GetHistory, + HistoryItem, + RemoveEntry, +} from "../../services/historyStore"; + +import "./home.css"; const { ipcRenderer } = electron; @@ -28,25 +39,28 @@ const Home = () => { sqliteParser, importedSqliteFilePath, } = useWorkbenchDB(); - + const navigate = useNavigate(); const [historyRefreshToken, setRefreshToken] = useState(0); const refreshHistory = () => setRefreshToken(Math.random()); - const history = useMemo(GetHistory, [importedSqliteFilePath, db, historyRefreshToken]); + const history = useMemo(GetHistory, [ + importedSqliteFilePath, + db, + historyRefreshToken, + ]); - function deleteEntry(entry: HistoryItem, showToast=true){ + function deleteEntry(entry: HistoryItem, showToast = true) { RemoveEntry(entry); refreshHistory(); - if(showToast) - toast('Removed item', { type: 'success' }); + if (showToast) toast.success("Removed item"); } - function reportInvalidEntry(entry: HistoryItem, entryType: string){ - toast(`Selected ${entryType} file doesn't exist`, { type: 'error' }); + function reportInvalidEntry(entry: HistoryItem, entryType: string) { + toast.error(`Selected ${entryType} file doesn't exist`); deleteEntry(entry, false); } - function historyItemParser(historyItem: HistoryItem){ - if(historyItem.json_path){ + function historyItemParser(historyItem: HistoryItem) { + if (historyItem.json_path) { if (!electronFs.existsSync(historyItem.json_path)) { return reportInvalidEntry(historyItem, "JSON"); } @@ -55,7 +69,7 @@ const Home = () => { if (!electronFs.existsSync(historyItem.sqlite_path)) { return reportInvalidEntry(historyItem, "SQLite"); } - sqliteParser(historyItem.sqlite_path) + sqliteParser(historyItem.sqlite_path); } } @@ -67,11 +81,11 @@ const Home = () => { // Copy already created/imported sqlite file to new sqlite file, and // update path of workbench DB to new sqlite DB - const saveSqliteFile = () => ipcRenderer.send(OPEN_DIALOG_CHANNEL.SAVE_SQLITE); - + const saveSqliteFile = () => + ipcRenderer.send(OPEN_DIALOG_CHANNEL.SAVE_SQLITE); - if(!initialized && loadingStatus !== null){ - return + if (!initialized && loadingStatus !== null) { + return ; } return ( @@ -92,10 +106,7 @@ const Home = () => {
Import ScanCode JSON
- +
Open SQLite File
@@ -106,30 +117,37 @@ const Home = () => {
Save SQLite File
-
+
OR Simply drop your json / sqlite file anywhere in the app !!
-
+

Recent files

- { - history.map((historyItem, idx) => ( - - + - - - )) - } + ))}
- historyItemParser(historyItem)}> - { historyItem.json_path ? 'Import' : 'Open ' } + {history.map((historyItem, idx) => ( +
+ historyItemParser(historyItem)} + > + {historyItem.json_path ? "Import" : "Open "} - { historyItem.json_path || historyItem.sqlite_path } + + {historyItem.json_path || historyItem.sqlite_path} @@ -138,24 +156,26 @@ const Home = () => { - - deleteEntry(historyItem)} /> + + + deleteEntry(historyItem)} + />
-
+

Quick Links

-
+
{
); -} +}; -export default Home; \ No newline at end of file +export default Home; diff --git a/src/pages/PackageInfoDash/PackageInfoDash.tsx b/src/pages/PackageInfoDash/PackageInfoDash.tsx index 7c125c01..a02e9a37 100644 --- a/src/pages/PackageInfoDash/PackageInfoDash.tsx +++ b/src/pages/PackageInfoDash/PackageInfoDash.tsx @@ -1,85 +1,98 @@ -import { Op, WhereOptions } from 'sequelize'; -import { Row, Col, Card } from 'react-bootstrap'; -import React, { useEffect, useState } from 'react' +import { Op, WhereOptions } from "sequelize"; +import { Row, Col, Card } from "react-bootstrap"; +import React, { useEffect, useState } from "react"; -import { formatChartData } from '../../utils/pie'; -import { useWorkbenchDB } from '../../contexts/workbenchContext'; -import PieChart from '../../components/PieChart/PieChart'; -import EllipticLoader from '../../components/EllipticLoader'; +import { formatChartData } from "../../utils/pie"; +import { useWorkbenchDB } from "../../contexts/workbenchContext"; +import PieChart from "../../components/PieChart/PieChart"; +import EllipticLoader from "../../components/EllipticLoader"; interface ScanData { - totalPackages: number | null, + totalPackages: number | null; } import "./PackageInfoDash.css"; -import { FileAttributes } from '../../services/models/file'; -import { NO_VALUE_DETECTED_LABEL } from '../../constants/data'; +import { FileAttributes } from "../../services/models/file"; +import { NO_VALUE_DETECTED_LABEL } from "../../constants/data"; const PackageInfoDash = () => { - const workbenchDB = useWorkbenchDB(); const [packageTypeData, setPackageTypeData] = useState(null); const [packageLangData, setPackageLangData] = useState(null); const [packageLicenseData, setPackageLicenseData] = useState(null); const [scanData, setScanData] = useState({ totalPackages: null, - }) - + }); + useEffect(() => { const { db, initialized, currentPath } = workbenchDB; - - if(!initialized || !db || !currentPath) - return; + + if (!initialized || !db || !currentPath) return; const where: WhereOptions = { path: { [Op.or]: [ - { [Op.like]: `${currentPath}`}, // Matches a file / directory. - { [Op.like]: `${currentPath}/%`} // Matches all its children (if any). - ] - } + { [Op.like]: `${currentPath}` }, // Matches a file / directory. + { [Op.like]: `${currentPath}/%` }, // Matches all its children (if any). + ], + }, }; - db.sync.then(db => db.File.findAll({ - where, - // attributes: ['id'], - })) - .then((files) =>{ - const fileIDs = files.map(file => file.getDataValue('id')); - + db.sync + .then((db) => + db.File.findAll({ + where, + // attributes: ['id'], + }) + ) + .then((files) => { + const fileIDs = files.map((file) => file.getDataValue("id")); + // Query and prepare chart for package types db.sync - .then(db => db.PackageData.findAll({where: { fileId: fileIDs }})) - .then(packageData => { - // Prepare count of total packages - // console.log("All packages", packages.map(pkg => pkg.get({ plain: true }))); + .then((db) => db.PackageData.findAll({ where: { fileId: fileIDs } })) + .then((packageData) => { + // Prepare count of packages setScanData({ totalPackages: packageData.length }); return packageData; }) - .then(packageData => { + .then((packageData) => { // Prepare chart for package types const packageTypes = packageData.map( - packageEntry => packageEntry.getDataValue('type') || NO_VALUE_DETECTED_LABEL + (packageEntry) => + packageEntry.getDataValue("type") || NO_VALUE_DETECTED_LABEL + ); + const { chartData: packageTypesChartData } = formatChartData( + packageTypes, + "package types" ); - const { chartData: packageTypesChartData } = formatChartData(packageTypes, 'package types'); // console.log("Result packages types:", packageTypesChartData); setPackageTypeData(packageTypesChartData); // Prepare chart for package languages const packageLangs = packageData.map( - packageEntry => packageEntry.getDataValue('primary_language') || NO_VALUE_DETECTED_LABEL + (packageEntry) => + packageEntry.getDataValue("primary_language") || + NO_VALUE_DETECTED_LABEL + ); + const { chartData: packageLangsChartData } = formatChartData( + packageLangs, + "package langs" ); - const { chartData: packageLangsChartData } = formatChartData(packageLangs, 'package langs'); // console.log("Result packages languages:", packageLangsChartData); setPackageLangData(packageLangsChartData); // Prepare chart for package license expression const packageLicenseExp = packageData.map( - packageEntry => packageEntry.getDataValue('declared_license_expression') || NO_VALUE_DETECTED_LABEL + (packageEntry) => + packageEntry.getDataValue("declared_license_expression") || + NO_VALUE_DETECTED_LABEL + ); + const { chartData: packageLicenseExpChartData } = formatChartData( + packageLicenseExp, + "package license exp" ); - const { chartData: packageLicenseExpChartData } = - formatChartData(packageLicenseExp, 'package license exp'); - + // console.log("Result packages license exp:", packageLicenseExpChartData); setPackageLicenseData(packageLicenseExpChartData); }); @@ -87,71 +100,61 @@ const PackageInfoDash = () => { }, [workbenchDB]); return ( -
-
-

- Package info - { workbenchDB.currentPath || ""} -

-

+
+
+

Package info - {workbenchDB.currentPath || ""}

+
+
- - - { - scanData.totalPackages === null ? - - : -

- { scanData.totalPackages } -

- } -
- Total Number of packages -
+ + + {scanData.totalPackages === null ? ( + + ) : ( +

{scanData.totalPackages}

+ )} +
Total Number of packages
-

+
+
- -
- Package Types -
+ +
Package Types
- -
- Package languages -
+ +
Package languages
- -
- Package Licenses -
+ +
Package Licenses
-

+
+
- ) -} + ); +}; -export default PackageInfoDash \ No newline at end of file +export default PackageInfoDash; diff --git a/src/services/models/packages.ts b/src/services/models/packages.ts index 7e0657cc..d77e094a 100644 --- a/src/services/models/packages.ts +++ b/src/services/models/packages.ts @@ -14,53 +14,61 @@ # */ -import { Sequelize, StringDataType, IntegerDataType, DataTypes, Model } from 'sequelize'; -import { jsonDataType, JSON_Type } from './databaseUtils'; +import { + Sequelize, + StringDataType, + IntegerDataType, + DataTypes, + Model, +} from "sequelize"; +import { jsonDataType, JSON_Type } from "./databaseUtils"; export interface PackagesAttributes { id: IntegerDataType; - type: StringDataType, - namespace: StringDataType | null, - name: StringDataType, - version: StringDataType | null, - qualifiers: JSON_Type, - subpath: StringDataType | null, - primary_language: StringDataType | null, - description: StringDataType | null, - release_date: StringDataType | null, - parties: JSON_Type, - keywords: JSON_Type, - homepage_url: StringDataType | null, - download_url: StringDataType | null, - size: StringDataType | null, - sha1: StringDataType | null, - md5: StringDataType | null, - sha256: StringDataType | null, - sha512: StringDataType | null, - bug_tracking_url: StringDataType | null, - code_view_url: StringDataType | null, - vcs_url: StringDataType | null, - copyright: StringDataType | null, - declared_license_expression: StringDataType | null, - declared_license_expression_spdx: StringDataType | null, - other_license_expression: StringDataType | null, - other_license_expression_spdx: StringDataType | null, - extracted_license_statement: JSON_Type | null, - notice_text: StringDataType | null, - source_packages: JSON_Type, - extra_data: JSON_Type, - repository_homepage_url: StringDataType | null, - repository_download_url: StringDataType | null, - api_data_url: StringDataType | null, - package_uid: StringDataType, - datafile_paths: JSON_Type, - datasource_ids: JSON_Type, - purl: StringDataType, + type: StringDataType; + namespace: StringDataType | null; + name: StringDataType; + version: StringDataType | null; + qualifiers: JSON_Type; + subpath: StringDataType | null; + primary_language: StringDataType | null; + description: StringDataType | null; + release_date: StringDataType | null; + parties: JSON_Type; + keywords: JSON_Type; + homepage_url: StringDataType | null; + download_url: StringDataType | null; + size: StringDataType | null; + sha1: StringDataType | null; + md5: StringDataType | null; + sha256: StringDataType | null; + sha512: StringDataType | null; + bug_tracking_url: StringDataType | null; + code_view_url: StringDataType | null; + vcs_url: StringDataType | null; + copyright: StringDataType | null; + declared_license_expression: StringDataType | null; + declared_license_expression_spdx: StringDataType | null; + license_detections: JSON_Type; + other_license_expression: StringDataType | null; + other_license_expression_spdx: StringDataType | null; + other_license_detections: JSON_Type; + extracted_license_statement: JSON_Type | null; + notice_text: StringDataType | null; + source_packages: JSON_Type; + extra_data: JSON_Type; + repository_homepage_url: StringDataType | null; + repository_download_url: StringDataType | null; + api_data_url: StringDataType | null; + package_uid: StringDataType; + datafile_paths: JSON_Type; + datasource_ids: JSON_Type; + purl: StringDataType; } export default function packagesModel(sequelize: Sequelize) { return sequelize.define>( - 'packages', + "packages", { id: { allowNull: false, @@ -78,7 +86,7 @@ export default function packagesModel(sequelize: Sequelize) { allowNull: true, type: DataTypes.STRING, }, - qualifiers: jsonDataType('qualifiers'), + qualifiers: jsonDataType("qualifiers"), subpath: { allowNull: true, type: DataTypes.STRING, @@ -95,8 +103,8 @@ export default function packagesModel(sequelize: Sequelize) { allowNull: true, type: DataTypes.STRING, }, - parties: jsonDataType('parties'), - keywords: jsonDataType('keywords'), + parties: jsonDataType("parties"), + keywords: jsonDataType("keywords"), homepage_url: { allowNull: true, type: DataTypes.STRING, @@ -149,6 +157,7 @@ export default function packagesModel(sequelize: Sequelize) { allowNull: true, type: DataTypes.STRING, }, + license_detections: jsonDataType("license_detections"), other_license_expression: { allowNull: true, type: DataTypes.STRING, @@ -157,13 +166,14 @@ export default function packagesModel(sequelize: Sequelize) { allowNull: true, type: DataTypes.STRING, }, - extracted_license_statement: jsonDataType('extracted_license_statement'), + other_license_detections: jsonDataType("other_license_detections"), + extracted_license_statement: jsonDataType("extracted_license_statement"), notice_text: { allowNull: true, type: DataTypes.STRING, }, - source_packages: jsonDataType('source_packages'), - extra_data: jsonDataType('extra_data'), + source_packages: jsonDataType("source_packages"), + extra_data: jsonDataType("extra_data"), repository_homepage_url: { allowNull: true, type: DataTypes.STRING, @@ -177,14 +187,15 @@ export default function packagesModel(sequelize: Sequelize) { type: DataTypes.STRING, }, package_uid: DataTypes.STRING, - datafile_paths: jsonDataType('datafile_paths'), - datasource_ids: jsonDataType('datasource_ids'), + datafile_paths: jsonDataType("datafile_paths"), + datasource_ids: jsonDataType("datasource_ids"), purl: { allowNull: true, type: DataTypes.STRING, }, }, { - timestamps: false - }); -} \ No newline at end of file + timestamps: false, + } + ); +} diff --git a/src/services/workbenchDB.ts b/src/services/workbenchDB.ts index 2691fc22..ca7d6ee1 100644 --- a/src/services/workbenchDB.ts +++ b/src/services/workbenchDB.ts @@ -349,7 +349,15 @@ export class WorkbenchDB { .then(() => this.db.Packages.bulkCreate(packages)) .then(() => this.db.Dependencies.bulkCreate(dependencies)) .then(() => this.db.Header.create(parsedHeader)) - .then((header) => (headerId = Number(header.getDataValue("id")))); + .then((header) => (headerId = Number(header.getDataValue("id")))) + .catch((err: unknown) => { + console.error( + "Some error parsing Top level data (caught in workbenchDB) !!", + err, + TopLevelData + ); + reject(err); + }); console.log( "\n----------------------------------------------------------------\n" @@ -364,15 +372,17 @@ export class WorkbenchDB { ); // Handle absence of detection.identifier in matches at file level in prev toolkit versions // upto v32.0.0rc2 - const for_license_detections: string[] = file.for_license_detections || []; + const for_license_detections: string[] = + file.for_license_detections || []; file?.license_detections?.forEach( (detection: any, detectionIdx: number) => { - const detectionIdentifier = detection.identifier || for_license_detections[detectionIdx]; + const detectionIdentifier = + detection.identifier || for_license_detections[detectionIdx]; const targetLicenseDetection: any = TopLevelData.license_detections_map.get(detectionIdentifier); - + if (!targetLicenseDetection) return; if (!targetLicenseDetection.file_regions) targetLicenseDetection.file_regions = []; @@ -573,7 +583,16 @@ export class WorkbenchDB { }) .catch((e: unknown) => reject(e)); }) - .on("error", (e: unknown) => reject(e)); + .on("error", (err: unknown) => { + console.error( + "Some error parsing data (caught in workbenchDB) !!", + err + ); + toast.error( + "Some error parsing data !! \nPlease check console for more info" + ); + reject(err); + }); }); } @@ -741,7 +760,12 @@ export class WorkbenchDB { ) .catch((err) => { - console.error("Some error parsing data !!", err); + console.error( + "Some error adding files data (caught in workbenchDB) !!", + err, + files, + options + ); toast.error( "Some error parsing data !! \nPlease check console for more info" );