Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 15 additions & 16 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": {
"base": "dist/frontend"
},
"outputPath": "dist/frontend",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": [
"zone.js",
"@angular/localize/init"
"zone.js"
],
"tsConfig": "tsconfig.app.json",
"assets": [
Expand All @@ -30,27 +28,28 @@
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.css"
],
"scripts": [],
"browser": "src/main.ts"
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
"maximumWarning": "1mb",
"maximumError": "2mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "5kb"
"maximumWarning": "10kb",
"maximumError": "10kb"
}
],
"outputHashing": "all"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
Expand All @@ -62,18 +61,18 @@
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"buildTarget": "frontend:build:production"
"browserTarget": "frontend:build:production"
},
"development": {
"buildTarget": "frontend:build:development"
"browserTarget": "frontend:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"buildTarget": "frontend:build"
"browserTarget": "frontend:build"
}
},
"test": {
Expand All @@ -98,6 +97,6 @@
}
},
"cli": {
"analytics": false
"analytics": "0812ed0f-7fe3-4ead-911a-474b02068946"
}
}
80 changes: 74 additions & 6 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const url = require("url");
const path = require("path");

let mainWindow;
let zipPaths = [];

function createWindow() {
mainWindow = new BrowserWindow({
Expand All @@ -21,7 +22,7 @@ function createWindow() {

mainWindow.loadURL(
url.format({
pathname: path.join(__dirname, `/dist/frontend/browser/index.html`),
pathname: path.join(__dirname, `/dist/frontend/index.html`),
protocol: "file:",
slashes: true,
})
Expand Down Expand Up @@ -52,31 +53,98 @@ ipcMain.handle("selectFiles", async () => {

ipcMain.handle("getZipFromFolder", async () => {
return new Promise(async(resolve, reject) => {
console.log('[Electron] Opening folder dialog...');
let folder = await dialog.showOpenDialog(mainWindow, {
properties: ["openDirectory"],
});

if(folder.filePaths.length === 1) {
let zipPath = folder.filePaths[0];
let tempPath = path.join(__dirname, "temp.zip");

zipPaths = [zipPath, tempPath];
console.log('[Electron] Folder selected:', zipPath);
console.log('[Electron] Will zip to:', tempPath);

return resolve(true);
}

console.log('[Electron] No folder selected or cancelled');
return reject(false);
})
});

ipcMain.handle("zipDirectory", async() => {
return new Promise(async(resolve, reject) => {
try {
const { zip } = await import('zip-a-folder');
await zip(zipPaths[0], zipPaths[1]);
const fileData = await fs.promises.readFile(zipPaths[1]);
return resolve(fileData);
console.log('[Electron] Starting zip of:', zipPaths[0]);
console.log('[Electron] Output path:', zipPaths[1]);

// Check if node_modules exists and warn about size
const nodeModulesPath = path.join(zipPaths[0], 'node_modules');
const hasNodeModules = fs.existsSync(nodeModulesPath);

if (hasNodeModules) {
console.log('[Electron] WARNING: node_modules detected - excluding from zip for faster processing');
console.log('[Electron] OSI will run npm install automatically if needed');
}

// Dynamic import for ES modules
const { zip } = await import("zip-a-folder");
const archiver = await import("archiver");
const streamBuffers = await import("stream-buffers");

// Create a buffer to store the zip
const outputStreamBuffer = new streamBuffers.default.WritableStreamBuffer({
initialSize: (100 * 1024),
incrementAmount: (10 * 1024)
});

// Create archive with exclusions
const archive = archiver.default('zip', {
zlib: { level: 5 } // Moderate compression for speed
});

archive.on('error', (err) => {
console.error('[Electron] Archive error:', err);
reject(err);
});

archive.on('end', async () => {
console.log('[Electron] Archive finalized, size:', archive.pointer(), 'bytes');
const buffer = outputStreamBuffer.getContents();

// Write to temp file
await fs.promises.writeFile(zipPaths[1], buffer);
console.log('[Electron] Zip file written to:', zipPaths[1]);

return resolve(buffer);
});

// Pipe archive to buffer
archive.pipe(outputStreamBuffer);

// Add directory with exclusions
archive.glob('**/*', {
cwd: zipPaths[0],
ignore: [
'**/node_modules/**',
'**/.git/**',
'**/dist/**',
'**/build/**',
'**/.next/**',
'**/coverage/**',
'**/.cache/**',
'**/tmp/**',
'**/*.log'
]
});

console.log('[Electron] Creating optimized zip (excluding node_modules and build artifacts)...');
await archive.finalize();

} catch(error) {
console.error('[Electron] Zip error:', error);
return reject(error);
}
})
Expand Down
9 changes: 9 additions & 0 deletions doc/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased] - (11/22/25)
### Added
- Security Dashboard that surfaces per-project vulnerability totals, severity cards, active alerts, and historical trends, powered by the new backend history endpoints.
- Severity filters, project dropdowns, and improved toast workflows so users can acknowledge alerts and pivot between SBOMs faster.

### Changed
- Optimized the Electron zip routine to skip `node_modules`/build artifacts before sending projects to OSI, drastically reducing upload times.
- Raised the Angular `anyComponentStyle` budget to 10kb to eliminate noisy build warnings from rich views like upload/viewer.

## [v1.2.1] - (11/29/23)
### Added
- Support for XML CDX SBOM's in Convert and Generate added
Expand Down
Loading