import { fileURLToPath } from 'node:url'; import vue from '@vitejs/plugin-vue'; import tailwind from '@tailwindcss/vite'; import { createServer } from 'vite'; const server = await createServer({ configFile: false, plugins: [vue(), tailwind()], resolve: { alias: { '@': fileURLToPath(new URL('../../resources/js', import.meta.url)), }, }, server: { host: '127.0.0.1', port: 4176, strictPort: true, hmr: false }, appType: 'custom', }); const project = { id: 7, name: 'Engineering', key: 'ENG', show_author: true, show_story_points: true, }; const ticketType = { id: 1, name: 'Task', is_parent: false }; const priority = { id: 1, name: 'Medium' }; const status = { id: 1, name: 'To do', board_column: null }; let ticket = { id: 31, ticket_key: 'ENG-31', title: 'Existing ticket', description: '', ticket_type: ticketType, ticket_type_id: 1, ticket_priority: priority, ticket_priority_id: 1, ticket_status: status, is_blocked: false, story_points: 0, acceptance_criteria: [], field_values: [], worklog_entries: [], created_at: '2026-09-10T12:00:00Z', updated_at: '2026-09-11T12:00:00Z', }; server.middlewares.use(async (request, response, next) => { const url = new URL(request.url, 'http://localhost'); if (!/^\/(feedback|projects|dashboard)(\/|$)/.test(url.pathname)) { return next(); } let path = url.pathname; const mutation = request.method !== 'GET'; const result = request.headers.cookie?.match(/feedback_test_result=(\w+)/)?.[1] ?? 'success'; if (path.endsWith('/branches/validate')) { response.setHeader('Content-Type', 'application/json'); response.end(JSON.stringify({ is_valid: true, message: 'Available' })); return; } if (mutation) { if (result === 'server') { response.statusCode = 503; response.setHeader('Content-Type', 'text/html'); response.end('

Temporarily unavailable

'); return; } path = new URL(request.headers.referer).pathname; let body = ''; for await (const chunk of request) { body += chunk; } if (path === '/projects/7/tickets/31' && result === 'success') { ticket = { ...ticket, ...JSON.parse(body) }; } if (path === '/projects/7/tickets/create' && result === 'success') { path = '/projects/7/backlog'; } } const page = { component: path === '/feedback' ? 'FeedbackPreview' : path.endsWith('/tickets/create') ? 'TicketCreate' : path === '/projects/7/tickets/31' ? 'Ticket' : 'Destination', url: path, version: null, clearHistory: false, encryptHistory: false, props: { name: 'KanbanGit', sidebarOpen: true, auth: { permissions: { globalAdmin: true, projectCreate: true, canManageTeams: true, }, user: { id: 1, name: 'Alex Morgan', email: 'alex@example.test', avatar: null, }, }, navigation: { project: { ...project, canManage: true, canCreateTickets: true, }, }, errors: mutation && result === 'validation' ? { title: 'Use a different title.' } : {}, project, source: 'backlog', defaultTicketStatusId: 1, ticketTypes: [ticketType], ticketPriorities: [priority], ticketStatusOptions: [status], users: [], parentTicketOptions: [], canEditTicket: true, canManageProject: true, childTicketTree: [], linkedTickets: [], repositoryBranches: [], repositoryPullRequests: [], suggestedBranchName: 'feature/ENG-31-existing-ticket', ticket, ticketFieldDefinitions: [], ticketLinkOptions: [], ticketLinkTypes: [], }, }; response.setHeader('Vary', 'X-Inertia'); if (request.headers['x-inertia']) { response.setHeader('X-Inertia', 'true'); response.setHeader('Content-Type', 'application/json'); response.end(JSON.stringify(page)); return; } const escapedPage = JSON.stringify(page) .replaceAll('&', '&') .replaceAll('"', '"') .replaceAll('<', '<'); const html = '
'; response.setHeader('Content-Type', 'text/html'); response.end(await server.transformIndexHtml(request.url, html)); }); await server.listen(); console.log('Feedback fixture ready at http://127.0.0.1:4176/feedback');