//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format. //Copyright (C) 2024 HTWKalender support@htwkalender.de //This program is free software: you can redistribute it and/or modify //it under the terms of the GNU Affero General Public License as published by //the Free Software Foundation, either version 3 of the License, or //(at your option) any later version. //This program is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU Affero General Public License for more details. //You should have received a copy of the GNU Affero General Public License //along with this program. If not, see . import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import { fileURLToPath } from "node:url"; import { VitePWA } from "vite-plugin-pwa"; import basicSsl from "@vitejs/plugin-basic-ssl"; import resolve from "@rollup/plugin-node-resolve"; import {resolve as pathResolver} from "path"; import terser from "@rollup/plugin-terser"; import ViteSSGOptions from "vite-ssg"; import generateSitemap from 'vite-ssg-sitemap' import vueDevTools from 'vite-plugin-vue-devtools' const hostname = "https://cal.htwk-leipzig.de"; export default defineConfig({ plugins: [ vue(), resolve(), terser(), vueDevTools(), basicSsl(), VitePWA({ mode: "development", base: "/", injectRegister: "auto", includeAssets: ["favicon.ico", "apple-touch-icon.png", "mask-icon.svg"], manifest: { name: "HTWKalender", short_name: "HTWKalender", description: "Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.", theme_color: "#FFFFFF", background_color: "#FFFFFF", display: "standalone", start_url: "/", id: "de.htwk-leipzig.htwkalender", screenshots: [ { src: "/1280x720.png", sizes: "1280x720", form_factor: "wide", type: "image/png", }, { src: "/390x844.png", sizes: "1170x2532", form_factor: "narrow", type: "image/png", }, ], icons: [ { src: "/pwa-192x192.png", sizes: "192x192", type: "image/png", purpose: "any", }, { src: "/pwa-512x512.png", sizes: "512x512", type: "image/png", purpose: "any", }, { src: "/pwa-maskable-192x192.png", sizes: "192x192", type: "image/png", purpose: "maskable", }, { src: "/pwa-maskable-512x512.png", sizes: "512x512", type: "image/png", purpose: "maskable", }, ], }, registerType: "autoUpdate", workbox: { globPatterns: ["**/*.{js,css,html,ico,png,svg,json,vue,txt,woff2}"], cleanupOutdatedCaches: true, runtimeCaching: [ { urlPattern: ({ url }) => url.pathname.startsWith('/api/feed'), method: 'GET', handler: 'NetworkFirst', options: { cacheName: 'calendar-feed-cache', expiration: { maxAgeSeconds: 12 * 60 * 60, // 12 hours }, }, }, { urlPattern: /^https?.*/, handler: "NetworkFirst", options: { cacheName: "https-calls", expiration: { maxEntries: 150, maxAgeSeconds: 30 * 12 * 60 * 60, // 1 month }, networkTimeoutSeconds: 10, // fall back to cache if api does not response within 10 seconds }, }, ], }, devOptions: { enabled: true, /* when using generateSW the PWA plugin will switch to classic */ type: "module", navigateFallback: "index.html", suppressWarnings: true, }, }), ], resolve: { alias: { "@": fileURLToPath(new URL("./src", import.meta.url)), 'primevue' : pathResolver(__dirname, 'node_modules/primevue'), }, extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.css', '.scss'], }, ssgOptions: { script: "async", formatting: "minify", format: "esm", onFinished: () => { generateSitemap({ hostname: hostname, exclude: [ '/additional-modules', '/edit-additional-modules', '/edit-calendar', '/rename-modules', ] }) }, }, server: { host: true, port: 8000, watch: { usePolling: true, }, proxy: { "/api": { target: "http://localhost:8090/api", changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ""), }, }, }, esbuild: { supported: { "top-level-await": true, }, }, optimizeDeps: { esbuildOptions: { supported: { "top-level-await": true, }, }, }, build: { sourcemap: true, minify: "terser", terserOptions: { compress: { drop_console: true, }, }, cssMinify: "esbuild", cssCodeSplit: true, rollupOptions: { output: { manualChunks(id) { if (id.includes("node_modules")) { return id.toString().split("node_modules/")[1].split("/")[0].toString() } }, }, } }, });