fixes linter issues

This commit is contained in:
Peter Steinberger 2025-06-23 16:55:53 +02:00
parent 9101613351
commit 3351cc08c2
9 changed files with 92 additions and 48 deletions

View file

@ -462,7 +462,8 @@ export class FileBrowser extends LitElement {
}
// Fallback to simple diff display
const lines = this.diff!.diff.split('\n');
if (!this.diff) return html``;
const lines = this.diff.diff.split('\n');
return html`
<div class="overflow-auto h-full p-4 font-mono text-xs">
${lines.map((line) => {
@ -839,11 +840,22 @@ export class FileBrowser extends LitElement {
document.addEventListener('touchend', handleTouchEnd);
// Store handlers for removal
(this as any)._touchHandlers = { handleTouchStart, handleTouchEnd };
interface TouchHandlers {
handleTouchStart: (e: TouchEvent) => void;
handleTouchEnd: (e: TouchEvent) => void;
}
(this as unknown as { _touchHandlers: TouchHandlers })._touchHandlers = {
handleTouchStart,
handleTouchEnd,
};
}
private removeTouchHandlers() {
const handlers = (this as any)._touchHandlers;
interface TouchHandlers {
handleTouchStart: (e: TouchEvent) => void;
handleTouchEnd: (e: TouchEvent) => void;
}
const handlers = (this as unknown as { _touchHandlers?: TouchHandlers })._touchHandlers;
if (handlers) {
document.removeEventListener('touchstart', handlers.handleTouchStart);
document.removeEventListener('touchend', handlers.handleTouchEnd);

View file

@ -22,7 +22,7 @@ const logger = createLogger('monaco-editor');
// Import Monaco Editor types
declare global {
interface Window {
monaco: any;
monaco: typeof import('monaco-editor');
}
}

View file

@ -61,7 +61,7 @@ interface PushNotificationPayload {
}
// Install event
self.addEventListener('install', (event: ExtendableEvent) => {
self.addEventListener('install', (_event: ExtendableEvent) => {
console.log('[SW] Installing service worker');
// Force activation of new service worker
@ -158,8 +158,13 @@ async function handlePushNotification(payload: PushNotificationPayload): Promise
}
}
function getDefaultActions(data: NotificationData): any[] {
const baseActions: any[] = [
interface NotificationAction {
action: string;
title: string;
}
function getDefaultActions(data: NotificationData): NotificationAction[] {
const baseActions: NotificationAction[] = [
{
action: 'dismiss',
title: 'Dismiss',

View file

@ -11,8 +11,11 @@ const logger = createLogger('monaco-loader');
// Declare monaco on window
declare global {
interface Window {
monaco: any;
require: any;
monaco: typeof import('monaco-editor');
require: {
(dependencies: string[], callback: (...args: unknown[]) => void): void;
config: (config: { paths: { [key: string]: string } }) => void;
};
}
}
@ -42,8 +45,10 @@ async function loadMonacoEditor(): Promise<void> {
// Disable workers - they interfere with diff computation
// Monaco will fall back to synchronous mode which works fine
window.MonacoEnvironment = {
getWorker: function (_workerId: string, _label: string) {
return null as any;
getWorker: function (_workerId: string, _label: string): Worker {
// Return a dummy worker that will never be used
// Monaco will fall back to synchronous mode
return new Worker('data:,');
},
};
@ -150,7 +155,7 @@ export async function initializeMonaco(): Promise<void> {
/**
* Ensure Monaco is loaded and ready
*/
export async function ensureMonacoLoaded(): Promise<any> {
export async function ensureMonacoLoaded(): Promise<typeof import('monaco-editor')> {
await initializeMonaco();
return window.monaco;
}

View file

@ -205,8 +205,9 @@ export class OfflineNotificationManager {
return [];
}
const db = this.db;
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction([STORE_NAME], 'readonly');
const transaction = db.transaction([STORE_NAME], 'readonly');
const store = transaction.objectStore(STORE_NAME);
const index = store.index('nextRetry');
@ -229,8 +230,9 @@ export class OfflineNotificationManager {
throw new Error('Database not initialized');
}
const db = this.db;
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction([STORE_NAME], 'readwrite');
const transaction = db.transaction([STORE_NAME], 'readwrite');
const store = transaction.objectStore(STORE_NAME);
const request = store.add(notification);
@ -244,8 +246,9 @@ export class OfflineNotificationManager {
throw new Error('Database not initialized');
}
const db = this.db;
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction([STORE_NAME], 'readwrite');
const transaction = db.transaction([STORE_NAME], 'readwrite');
const store = transaction.objectStore(STORE_NAME);
const request = store.put(notification);
@ -259,8 +262,9 @@ export class OfflineNotificationManager {
throw new Error('Database not initialized');
}
const db = this.db;
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction([STORE_NAME], 'readwrite');
const transaction = db.transaction([STORE_NAME], 'readwrite');
const store = transaction.objectStore(STORE_NAME);
const request = store.delete(id);
@ -277,8 +281,9 @@ export class OfflineNotificationManager {
return { total: 0, pending: 0, failed: 0, lastProcessed: 0 };
}
const db = this.db;
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction([STORE_NAME], 'readonly');
const transaction = db.transaction([STORE_NAME], 'readonly');
const store = transaction.objectStore(STORE_NAME);
const request = store.getAll();
@ -311,8 +316,9 @@ export class OfflineNotificationManager {
return;
}
const db = this.db;
return new Promise((resolve, reject) => {
const transaction = this.db!.transaction([STORE_NAME], 'readwrite');
const transaction = db.transaction([STORE_NAME], 'readwrite');
const store = transaction.objectStore(STORE_NAME);
const request = store.clear();

View file

@ -530,7 +530,10 @@ export function createFilesystemRoutes(): Router {
logger.error(`Failed to get HEAD version of ./${relativePath}:`, error);
// Check if it's a stderr message
if (error instanceof Error && 'stderr' in error) {
logger.error(`Git stderr: ${(error as any).stderr}`);
const execError = error as Error & { stderr?: string };
if (execError.stderr) {
logger.error(`Git stderr: ${execError.stderr}`);
}
}
// For non-git repos, show no diff
originalContent = currentContent;

View file

@ -1,6 +1,7 @@
import { Router, Request, Response } from 'express';
import { VapidManager } from '../utils/vapid-manager.js';
import { PushNotificationService } from '../services/push-notification-service.js';
import { BellEventHandler } from '../services/bell-event-handler.js';
import { createLogger } from '../utils/logger.js';
const logger = createLogger('push-routes');
@ -8,25 +9,13 @@ const logger = createLogger('push-routes');
export interface CreatePushRoutesOptions {
vapidManager: VapidManager;
pushNotificationService: PushNotificationService | null;
bellEventHandler?: any;
bellEventHandler?: BellEventHandler;
}
export function createPushRoutes(options: CreatePushRoutesOptions): Router {
const { vapidManager, pushNotificationService } = options;
const router = Router();
// Helper function to check if push service is available
const checkPushService = (res: Response): boolean => {
if (!pushNotificationService) {
res.status(503).json({
error: 'Push notifications not initialized',
message: 'Push notification service is not available',
});
return false;
}
return true;
};
/**
* Get VAPID public key for client registration
*/
@ -65,7 +54,12 @@ export function createPushRoutes(options: CreatePushRoutesOptions): Router {
* Subscribe to push notifications
*/
router.post('/push/subscribe', async (req: Request, res: Response) => {
if (!checkPushService(res)) return;
if (!pushNotificationService) {
return res.status(503).json({
error: 'Push notifications not initialized',
message: 'Push notification service is not available',
});
}
try {
const { endpoint, keys } = req.body;
@ -77,7 +71,7 @@ export function createPushRoutes(options: CreatePushRoutesOptions): Router {
});
}
const subscriptionId = await pushNotificationService!.addSubscription(endpoint, keys);
const subscriptionId = await pushNotificationService.addSubscription(endpoint, keys);
res.json({
success: true,
@ -99,7 +93,12 @@ export function createPushRoutes(options: CreatePushRoutesOptions): Router {
* Unsubscribe from push notifications
*/
router.post('/push/unsubscribe', async (req: Request, res: Response) => {
if (!checkPushService(res)) return;
if (!pushNotificationService) {
return res.status(503).json({
error: 'Push notifications not initialized',
message: 'Push notification service is not available',
});
}
try {
const { endpoint } = req.body;
@ -112,11 +111,11 @@ export function createPushRoutes(options: CreatePushRoutesOptions): Router {
}
// For simplicity, we'll find and remove by endpoint
const subscriptions = pushNotificationService!.getSubscriptions();
const subscriptions = pushNotificationService.getSubscriptions();
const subscription = subscriptions.find((sub) => sub.endpoint === endpoint);
if (subscription) {
await pushNotificationService!.removeSubscription(subscription.id);
await pushNotificationService.removeSubscription(subscription.id);
logger.log(`Push subscription removed: ${subscription.id}`);
}
@ -137,10 +136,15 @@ export function createPushRoutes(options: CreatePushRoutesOptions): Router {
* Send test notification
*/
router.post('/push/test', async (req: Request, res: Response) => {
if (!checkPushService(res)) return;
if (!pushNotificationService) {
return res.status(503).json({
error: 'Push notifications not initialized',
message: 'Push notification service is not available',
});
}
try {
const result = await pushNotificationService!.sendNotification({
const result = await pushNotificationService.sendNotification({
type: 'test',
title: '🔔 Test Notification',
body: 'This is a test notification from VibeTunnel',
@ -178,10 +182,15 @@ export function createPushRoutes(options: CreatePushRoutesOptions): Router {
* Get service status
*/
router.get('/push/status', (req: Request, res: Response) => {
if (!checkPushService(res)) return;
if (!pushNotificationService) {
return res.status(503).json({
error: 'Push notifications not initialized',
message: 'Push notification service is not available',
});
}
try {
const subscriptions = pushNotificationService!.getSubscriptions();
const subscriptions = pushNotificationService.getSubscriptions();
res.json({
enabled: vapidManager.isEnabled(),

View file

@ -7,6 +7,7 @@
import { SessionInfo } from '../../shared/types.js';
import { createLogger } from '../utils/logger.js';
import { PushNotificationService } from './push-notification-service.js';
const logger = createLogger('bell-event-handler');
@ -45,7 +46,7 @@ export interface BellNotificationPayload {
* Ultra-simple bell event handler
*/
export class BellEventHandler {
private pushNotificationService: any = null;
private pushNotificationService: PushNotificationService | null = null;
constructor() {
logger.debug('BellEventHandler initialized');
@ -54,7 +55,7 @@ export class BellEventHandler {
/**
* Set the push notification service for sending notifications
*/
setPushNotificationService(service: any): void {
setPushNotificationService(service: PushNotificationService): void {
this.pushNotificationService = service;
logger.debug('Push notification service configured');
}

View file

@ -45,7 +45,7 @@ export interface NotificationPayload {
action: string;
title: string;
}>;
data?: any;
data?: Record<string, unknown>;
}
/**
@ -195,13 +195,15 @@ export class PushNotificationService {
const shouldRemove = this.shouldRemoveSubscription(error);
if (shouldRemove) {
this.subscriptions.delete(subscription.id);
const webPushError = error as Error & { statusCode?: number };
logger.log(
`Removed expired subscription: ${subscription.id} (status: ${(error as any).statusCode})`
`Removed expired subscription: ${subscription.id} (status: ${webPushError.statusCode})`
);
} else {
// Debug log for unhandled errors
const webPushError = error as Error & { statusCode?: number };
logger.debug(
`Not removing subscription ${subscription.id}, error: ${error instanceof Error ? error.message : String(error)}, statusCode: ${(error as any).statusCode}`
`Not removing subscription ${subscription.id}, error: ${error instanceof Error ? error.message : String(error)}, statusCode: ${webPushError.statusCode}`
);
}
}
@ -254,7 +256,7 @@ export class PushNotificationService {
// Check for HTTP 410 Gone status (subscription expired)
// WebPushError has a statusCode property
const webPushError = error as any;
const webPushError = error as Error & { statusCode?: number };
if (webPushError.statusCode === 410) {
return true;
}
@ -315,7 +317,8 @@ export class PushNotificationService {
logger.debug(`Loaded ${subscriptions.length} subscriptions`);
} catch (error) {
if ((error as any).code === 'ENOENT') {
const fsError = error as NodeJS.ErrnoException;
if (fsError.code === 'ENOENT') {
logger.debug('No existing subscriptions file found');
} else {
logger.error('Failed to load subscriptions:', error);