-
+
+
{{ item.Title }}
{{ item.Description }}
- {{ item.PrimaryURL }}
+ {{ item.PrimaryURL }}
|
-
+
Copy .trivyignore to Clipboard
-
-
-
diff --git a/src/components/README.md b/src/components/README.md
new file mode 100644
index 00000000..13e69e14
--- /dev/null
+++ b/src/components/README.md
@@ -0,0 +1,35 @@
+# Components
+
+Vue template files in this folder are automatically imported.
+
+## 🚀 Usage
+
+Importing is handled by [unplugin-vue-components](https://github.com/unplugin/unplugin-vue-components). This plugin automatically imports `.vue` files created in the `src/components` directory, and registers them as global components. This means that you can use any component in your application without having to manually import it.
+
+The following example assumes a component located at `src/components/MyComponent.vue`:
+
+```vue
+
+
+
+
+
+
+
+```
+
+When your template is rendered, the component's import will automatically be inlined, which renders to this:
+
+```vue
+
+
+
+
+
+
+
+```
diff --git a/src/components/ReportUrlFetcher.vue b/src/components/ReportUrlFetcher.vue
index 24b568e8..962cf4a0 100644
--- a/src/components/ReportUrlFetcher.vue
+++ b/src/components/ReportUrlFetcher.vue
@@ -1,141 +1,120 @@
-
-
-
-
-
- mdi-shield-lock
-
+
+
+
+
+ mdi-shield-lock
+
+
+
+
+ Authorization
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The data will be stored in the localStorage of your Browser and is
+ added as a header to the fetch call. If you want to fetch a report
+ from a
+ GitLab Job
+ , you need to add the PRIVATE-TOKEN header and set it to a
+ personal access token
+ with the scope read_api.
+
+
+
+
+
+
+
+ Save&Close
-
-
-
- Authorization
-
-
-
-
-
-
-
-
-
-
-
-
-
- The data will be stored in the localStorage of your Browser and
- is added as a header to the fetch call. If you want to fetch a
- report from a
- GitLab Job
- , you need to add the PRIVATE-TOKEN header and set it to a
- personal access token
- with the scope read_api.
-
-
-
-
-
-
-
- Save&Close
-
-
-
-
-
- Fetch
-
-
+
+
+
+
+ Fetch
+
-
diff --git a/src/layouts/README.md b/src/layouts/README.md
new file mode 100644
index 00000000..4016af35
--- /dev/null
+++ b/src/layouts/README.md
@@ -0,0 +1,5 @@
+# Layouts
+
+Layouts are reusable components that wrap around pages. They are used to provide a consistent look and feel across multiple pages.
+
+Full documentation for this feature can be found in the Official [vite-plugin-vue-layouts](https://github.com/JohnCampionJr/vite-plugin-vue-layouts) repository.
diff --git a/src/layouts/default.vue b/src/layouts/default.vue
new file mode 100644
index 00000000..01ba08d7
--- /dev/null
+++ b/src/layouts/default.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/main.ts b/src/main.ts
index 7deec3e4..54a09c85 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,13 +1,20 @@
-import Vue from "vue"
+/**
+ * main.ts
+ *
+ * Bootstraps Vuetify and other plugins then mounts the App`
+ */
+
+// Plugins
+import { registerPlugins } from "@/plugins"
+
+// Components
import App from "./App.vue"
-import router from "./router"
-import vuetify from "./plugins/vuetify"
-Vue.config.productionTip = false
+// Composables
+import { createApp } from "vue"
+
+const app = createApp(App)
+
+registerPlugins(app)
-new Vue({
- router,
- data: { vulnerabilities: undefined },
- vuetify,
- render: (h) => h(App),
-}).$mount("#app")
+app.mount("#app")
diff --git a/src/pages/README.md b/src/pages/README.md
new file mode 100644
index 00000000..341536c2
--- /dev/null
+++ b/src/pages/README.md
@@ -0,0 +1,5 @@
+# Pages
+
+Vue components created in this folder will automatically be converted to navigatable routes.
+
+Full documentation for this feature can be found in the Official [unplugin-vue-router](https://github.com/posva/unplugin-vue-router) repository.
diff --git a/src/views/Home.vue b/src/pages/index.vue
similarity index 60%
rename from src/views/Home.vue
rename to src/pages/index.vue
index 6bc6de00..a93da36c 100644
--- a/src/views/Home.vue
+++ b/src/pages/index.vue
@@ -22,7 +22,7 @@
-
+
There is no data to display yet. Try to load a trivy report by using
the file uploader above.
-
diff --git a/src/plugins/README.md b/src/plugins/README.md
new file mode 100644
index 00000000..62201c7c
--- /dev/null
+++ b/src/plugins/README.md
@@ -0,0 +1,3 @@
+# Plugins
+
+Plugins are a way to extend the functionality of your Vue application. Use this folder for registering plugins that you want to use globally.
diff --git a/src/plugins/index.ts b/src/plugins/index.ts
new file mode 100644
index 00000000..066bf4c8
--- /dev/null
+++ b/src/plugins/index.ts
@@ -0,0 +1,19 @@
+import router from "../router"
+
+/**
+ * plugins/index.ts
+ *
+ * Automatically included in `./src/main.ts`
+ */
+
+// Plugins
+import vuetify from "./vuetify"
+import Clipboard from "v-clipboard"
+
+// Types
+import type { App } from "vue"
+
+export function registerPlugins(app: App) {
+ app.use(vuetify).use(router)
+ app.use(Clipboard).use(router)
+}
diff --git a/src/plugins/v-clipboard.d.ts b/src/plugins/v-clipboard.d.ts
new file mode 100644
index 00000000..55c08783
--- /dev/null
+++ b/src/plugins/v-clipboard.d.ts
@@ -0,0 +1 @@
+declare module "v-clipboard"
diff --git a/src/plugins/vuetify.ts b/src/plugins/vuetify.ts
index 2eb7df91..bb5fd274 100644
--- a/src/plugins/vuetify.ts
+++ b/src/plugins/vuetify.ts
@@ -1,6 +1,23 @@
-import Vue from "vue"
-import Vuetify from "vuetify/lib/framework"
+// Composables
+import { createVuetify } from "vuetify"
-Vue.use(Vuetify)
+/**
+ * plugins/vuetify.ts
+ *
+ * Framework documentation: https://vuetifyjs.com`
+ */
-export default new Vuetify({})
+// Styles
+import "@mdi/font/css/materialdesignicons.css"
+import "vuetify/styles"
+import { VFileUpload } from "vuetify/labs/VFileUpload"
+
+// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
+export default createVuetify({
+ theme: {
+ defaultTheme: "light",
+ },
+ components: {
+ VFileUpload,
+ },
+})
diff --git a/src/router/index.ts b/src/router/index.ts
index 61040c7d..0f90c70c 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -1,21 +1,36 @@
-import Vue from "vue"
-import VueRouter, { RouteConfig } from "vue-router"
-import Home from "../views/Home.vue"
+/**
+ * router/index.ts
+ *
+ * Automatic routes for `./src/pages/*.vue`
+ */
-Vue.use(VueRouter)
+// Composables
+import { createRouter, createWebHistory } from "vue-router/auto"
+import { setupLayouts } from "virtual:generated-layouts"
+import { routes } from "vue-router/auto-routes"
-const routes: Array = [
- {
- path: "/",
- name: "Home",
- component: Home,
- props: (route) => ({ presetUrl: route.query.url }),
- },
-]
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: setupLayouts(routes),
+})
+
+// Workaround for https://github.com/vitejs/vite/issues/11804
+router.onError((err, to) => {
+ if (err?.message?.includes?.("Failed to fetch dynamically imported module")) {
+ if (!localStorage.getItem("vuetify:dynamic-reload")) {
+ console.log("Reloading page to fix dynamic import error")
+ localStorage.setItem("vuetify:dynamic-reload", "true")
+ location.assign(to.fullPath)
+ } else {
+ console.error("Dynamic import error, reloading page did not fix it", err)
+ }
+ } else {
+ console.error(err)
+ }
+})
-const router = new VueRouter({
- base: process.env.BASE_URL,
- routes,
+router.isReady().then(() => {
+ localStorage.removeItem("vuetify:dynamic-reload")
})
export default router
diff --git a/src/shims-tsx.d.ts b/src/shims-tsx.d.ts
deleted file mode 100644
index 2da51c06..00000000
--- a/src/shims-tsx.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import Vue, { VNode } from "vue"
-
-declare global {
- namespace JSX {
- // tslint:disable no-empty-interface
- interface Element extends VNode {}
- // tslint:disable no-empty-interface
- interface ElementClass extends Vue {}
- interface IntrinsicElements {
- [elem: string]: any
- }
- }
-}
diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts
deleted file mode 100644
index b3998276..00000000
--- a/src/shims-vue.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-declare module "*.vue" {
- import Vue from "vue"
- export default Vue
-}
diff --git a/src/shims-vuetify.d.ts b/src/shims-vuetify.d.ts
deleted file mode 100644
index 94eeeb22..00000000
--- a/src/shims-vuetify.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-declare module "vuetify/lib/framework" {
- import Vuetify from "vuetify"
- export default Vuetify
-}
diff --git a/src/styles/README.md b/src/styles/README.md
new file mode 100644
index 00000000..ea861794
--- /dev/null
+++ b/src/styles/README.md
@@ -0,0 +1,3 @@
+# Styles
+
+This directory is for configuring the styles of the application.
diff --git a/src/styles/settings.scss b/src/styles/settings.scss
new file mode 100644
index 00000000..01c0bc3c
--- /dev/null
+++ b/src/styles/settings.scss
@@ -0,0 +1,33 @@
+/**
+ * src/styles/settings.scss
+ *
+ * Configures SASS variables and Vuetify overwrites
+ */
+
+// https://vuetifyjs.com/features/sass-variables/`
+// @use 'vuetify/settings' with (
+// $color-pack: false
+// );
+
+.v-file-upload.v-file-upload--density-compact {
+ padding: 0.5rem;
+ border: 2px dashed #aaa;
+ margin: 0 0.5rem;
+}
+
+.v-file-upload--density-compact .v-file-upload-icon {
+ font-size: 1rem;
+}
+
+.v-file-upload-title {
+ font-size: 1rem;
+ font-weight: normal;
+}
+
+.v-file-upload-items .v-list-item--rounded {
+ border: none;
+}
+
+.v-file-upload-items > .v-list-item--density-default.v-list-item--two-line {
+ padding: 1rem 1rem 1rem 0;
+}
diff --git a/src/typed-router.d.ts b/src/typed-router.d.ts
new file mode 100644
index 00000000..331ee510
--- /dev/null
+++ b/src/typed-router.d.ts
@@ -0,0 +1,23 @@
+/* eslint-disable */
+/* prettier-ignore */
+// @ts-nocheck
+// Generated by unplugin-vue-router. ‼️ DO NOT MODIFY THIS FILE ‼️
+// It's recommended to commit this file.
+// Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry.
+
+declare module 'vue-router/auto-routes' {
+ import type {
+ RouteRecordInfo,
+ ParamValue,
+ ParamValueOneOrMore,
+ ParamValueZeroOrMore,
+ ParamValueZeroOrOne,
+ } from 'vue-router'
+
+ /**
+ * Route name map generated by unplugin-vue-router
+ */
+ export interface RouteNamedMap {
+ '/': RouteRecordInfo<'/', '/', Record, Record>,
+ }
+}
diff --git a/src/types/index.d.ts b/src/types.ts
similarity index 69%
rename from src/types/index.d.ts
rename to src/types.ts
index 1a117136..327bfe0a 100644
--- a/src/types/index.d.ts
+++ b/src/types.ts
@@ -1,4 +1,4 @@
-export declare interface VulnerabilityReportFile {
+export type VulnerabilityReportFile = {
SchemaVersion?: number
Results: VulnerabilityReportTarget[]
}
@@ -7,13 +7,13 @@ export type Version1OrVersion2 =
| VulnerabilityReportTarget[]
| VulnerabilityReportFile
-export declare interface VulnerabilityReportTarget {
+export type VulnerabilityReportTarget = {
Target: string
Type: string
Vulnerabilities?: Vulnerability[]
}
-export declare interface Vulnerability {
+export type Vulnerability = {
id?: number
Title: string
Description: string
@@ -26,7 +26,7 @@ export declare interface Vulnerability {
Target: string
}
-export declare interface VulnerabilitySeverityInformation {
+export type VulnerabilitySeverityInformation = {
severity: string
count: number
}
diff --git a/tsconfig.app.json b/tsconfig.app.json
new file mode 100644
index 00000000..e14c754d
--- /dev/null
+++ b/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/tsconfig.json b/tsconfig.json
index c26042d2..66b5e570 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,31 +1,11 @@
{
- "compilerOptions": {
- "target": "esnext",
- "module": "esnext",
- "strict": true,
- "jsx": "preserve",
- "importHelpers": true,
- "moduleResolution": "node",
- "skipLibCheck": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "experimentalDecorators": true,
- "sourceMap": true,
- "strictNullChecks": false,
- "baseUrl": ".",
- "types": ["webpack-env", "cypress"],
- "paths": {
- "@/*": ["src/*"]
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
},
- "lib": ["esnext", "dom", "dom.iterable", "scripthost"]
- },
- "include": [
- "src/**/*.ts",
- "src/**/*.tsx",
- "src/**/*.vue",
- "tests/**/*.ts",
- "tests/**/*.tsx",
- "cypress/**/*.ts"
- ],
- "exclude": ["node_modules"]
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
}
diff --git a/tsconfig.node.json b/tsconfig.node.json
new file mode 100644
index 00000000..5a0c6a54
--- /dev/null
+++ b/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node22/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/vite.config.mts b/vite.config.mts
new file mode 100644
index 00000000..08d1d292
--- /dev/null
+++ b/vite.config.mts
@@ -0,0 +1,75 @@
+// Plugins
+import AutoImport from "unplugin-auto-import/vite"
+import Components from "unplugin-vue-components/vite"
+import Fonts from "unplugin-fonts/vite"
+import Layouts from "vite-plugin-vue-layouts"
+import Vue from "@vitejs/plugin-vue"
+import VueRouter from "unplugin-vue-router/vite"
+import Vuetify, { transformAssetUrls } from "vite-plugin-vuetify"
+
+// Utilities
+import { defineConfig } from "vite"
+import { fileURLToPath, URL } from "node:url"
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ VueRouter({
+ dts: "src/typed-router.d.ts",
+ }),
+ Layouts(),
+ AutoImport({
+ imports: [
+ "vue",
+ {
+ "vue-router/auto": ["useRoute", "useRouter"],
+ },
+ ],
+ dts: "src/auto-imports.d.ts",
+ eslintrc: {
+ enabled: true,
+ },
+ vueTemplate: true,
+ }),
+ Components({
+ dts: "src/components.d.ts",
+ }),
+ Vue({
+ template: { transformAssetUrls },
+ }),
+ // https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin#readme
+ Vuetify({
+ autoImport: true,
+ styles: {
+ configFile: "src/styles/settings.scss",
+ },
+ }),
+ Fonts({
+ google: {
+ families: [
+ {
+ name: "Roboto",
+ styles: "wght@100;300;400;500;700;900",
+ },
+ ],
+ },
+ }),
+ ],
+ define: { "process.env": {} },
+ resolve: {
+ alias: {
+ "@": fileURLToPath(new URL("./src", import.meta.url)),
+ },
+ extensions: [".js", ".json", ".jsx", ".mjs", ".ts", ".tsx", ".vue"],
+ },
+ server: {
+ port: 8080,
+ },
+ css: {
+ preprocessorOptions: {
+ sass: {
+ api: "modern-compiler",
+ },
+ },
+ },
+})
diff --git a/vue.config.js b/vue.config.js
deleted file mode 100644
index 2ac78523..00000000
--- a/vue.config.js
+++ /dev/null
@@ -1,7 +0,0 @@
-module.exports = {
- transpileDependencies: ["vuetify"],
- publicPath: "./",
- configureWebpack: {
- devtool: "source-map",
- },
-}
|