108 lines
3.0 KiB
JavaScript
108 lines
3.0 KiB
JavaScript
import { defineConfig } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import { resolve } from 'node:path';
|
|
import { readFile, stat } from 'node:fs/promises';
|
|
|
|
const MANAGED_CATALOG_API_PATH = '/api/managed-stations.json';
|
|
|
|
async function loadManagedCatalogEnvelope(repoRoot) {
|
|
const candidates = [
|
|
resolve(repoRoot, 'public', 'stations.json'),
|
|
resolve(repoRoot, 'dist', 'stations.json'),
|
|
resolve(repoRoot, 'stations.json'),
|
|
];
|
|
let found = null;
|
|
for (const p of candidates) {
|
|
try {
|
|
const s = await stat(p);
|
|
if (s.isFile()) { found = { filePath: p, mtime: s.mtime }; break; }
|
|
} catch { /* try next */ }
|
|
}
|
|
if (!found) throw new Error('Managed catalog source file was not found.');
|
|
const raw = JSON.parse(await readFile(found.filePath, 'utf8'));
|
|
const stations = Array.isArray(raw) ? raw : raw.stations;
|
|
return { schemaVersion: 1, updatedAt: found.mtime.toISOString(), stations };
|
|
}
|
|
|
|
const buildStamp = `${Date.now()}`;
|
|
|
|
function managedCatalogApiPlugin() {
|
|
async function handleManagedCatalogRequest(req, res, next) {
|
|
if (!req.url) {
|
|
next();
|
|
return;
|
|
}
|
|
|
|
const requestUrl = new URL(req.url, 'http://127.0.0.1');
|
|
if (requestUrl.pathname !== MANAGED_CATALOG_API_PATH) {
|
|
next();
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const payload = await loadManagedCatalogEnvelope(process.cwd());
|
|
res.statusCode = 200;
|
|
res.setHeader('content-type', 'application/json; charset=utf-8');
|
|
res.setHeader('cache-control', 'no-store');
|
|
res.end(`${JSON.stringify(payload)}\n`);
|
|
} catch (error) {
|
|
res.statusCode = 500;
|
|
res.setHeader('content-type', 'application/json; charset=utf-8');
|
|
res.end(JSON.stringify({
|
|
error: 'Failed to load managed catalog',
|
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
}));
|
|
}
|
|
}
|
|
|
|
return {
|
|
name: 'managed-catalog-api',
|
|
configureServer(server) {
|
|
server.middlewares.use((req, res, next) => {
|
|
void handleManagedCatalogRequest(req, res, next);
|
|
});
|
|
},
|
|
configurePreviewServer(server) {
|
|
server.middlewares.use((req, res, next) => {
|
|
void handleManagedCatalogRequest(req, res, next);
|
|
});
|
|
},
|
|
};
|
|
}
|
|
|
|
export default defineConfig({
|
|
plugins: [react(), managedCatalogApiPlugin()],
|
|
base: './',
|
|
build: {
|
|
rollupOptions: {
|
|
input: {
|
|
main: resolve(process.cwd(), 'index.html'),
|
|
privacy: resolve(process.cwd(), 'privacy.html'),
|
|
},
|
|
output: {
|
|
entryFileNames: `assets/[name]-${buildStamp}-[hash].js`,
|
|
chunkFileNames: `assets/[name]-${buildStamp}-[hash].js`,
|
|
assetFileNames: `assets/[name]-${buildStamp}-[hash][extname]`,
|
|
},
|
|
},
|
|
},
|
|
server: {
|
|
host: '127.0.0.1',
|
|
port: 5173,
|
|
strictPort: false,
|
|
proxy: {
|
|
'/radio-si-data': {
|
|
target: 'https://data.radio.si',
|
|
changeOrigin: true,
|
|
secure: true,
|
|
rewrite: (path) => path.replace(/^\/radio-si-data/, ''),
|
|
},
|
|
},
|
|
},
|
|
preview: {
|
|
host: '127.0.0.1',
|
|
port: 4173,
|
|
strictPort: false,
|
|
},
|
|
});
|