chore: apply low-risk lint cleanup

This commit is contained in:
webadderall
2026-04-15 14:59:02 +10:00
parent 71e557c325
commit 0026698b17
5 changed files with 219 additions and 198 deletions
+1 -8
View File
@@ -93,14 +93,7 @@
"useGetterReturn": "error"
}
},
"includes": [
"**",
"**/dist",
"**/.eslintrc.cjs",
"**",
"**/dist",
"**/.eslintrc.cjs"
]
"includes": ["**", "**/dist", "**/.eslintrc.cjs", "**", "**/dist", "**/.eslintrc.cjs"]
},
"javascript": { "formatter": { "quoteStyle": "double" } },
"overrides": [
+20 -21
View File
@@ -1,23 +1,22 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.cjs",
"css": "src/index.css",
"baseColor": "stone",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.cjs",
"css": "src/index.css",
"baseColor": "stone",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
+153 -122
View File
@@ -5,37 +5,37 @@
* uninstall, enable/disable) and exposes them to the renderer via preload.
*/
import { BrowserWindow, ipcMain, dialog, shell } from 'electron';
import { BrowserWindow, dialog, ipcMain, shell } from "electron";
import {
discoverExtensions,
getRegisteredExtensions,
getExtension,
setExtensionStatus,
installExtensionFromPath,
uninstallExtension,
getExtensionsDirectory,
} from './extensionLoader';
discoverExtensions,
getExtension,
getExtensionsDirectory,
getRegisteredExtensions,
installExtensionFromPath,
setExtensionStatus,
uninstallExtension,
} from "./extensionLoader";
import {
searchMarketplace,
getMarketplaceExtension,
downloadAndInstallExtension,
fetchPendingReviews,
updateReviewStatus,
submitExtensionForReview,
} from './extensionMarketplace';
import type { ExtensionInfo, MarketplaceReviewStatus } from './extensionTypes';
downloadAndInstallExtension,
fetchPendingReviews,
getMarketplaceExtension,
searchMarketplace,
submitExtensionForReview,
updateReviewStatus,
} from "./extensionMarketplace";
import type { ExtensionInfo, MarketplaceReviewStatus } from "./extensionTypes";
/**
* Serialize extension info for IPC transfer (strip non-serializable fields).
*/
function serializeExtensionInfo(info: ExtensionInfo) {
return {
manifest: info.manifest,
status: info.status,
path: info.path,
error: info.error,
builtin: info.builtin ?? false,
};
return {
manifest: info.manifest,
status: info.status,
path: info.path,
error: info.error,
builtin: info.builtin ?? false,
};
}
/**
@@ -43,121 +43,152 @@ function serializeExtensionInfo(info: ExtensionInfo) {
* Call this once during app initialization (in main.ts).
*/
export function registerExtensionIpcHandlers(): void {
// Discover all extensions (builtin + user-installed)
ipcMain.handle('extensions:discover', async () => {
const extensions = await discoverExtensions();
return extensions.map(serializeExtensionInfo);
});
// Discover all extensions (builtin + user-installed)
ipcMain.handle("extensions:discover", async () => {
const extensions = await discoverExtensions();
return extensions.map(serializeExtensionInfo);
});
// List currently registered extensions
ipcMain.handle('extensions:list', () => {
return getRegisteredExtensions().map(serializeExtensionInfo);
});
// List currently registered extensions
ipcMain.handle("extensions:list", () => {
return getRegisteredExtensions().map(serializeExtensionInfo);
});
// Get a specific extension by ID
ipcMain.handle('extensions:get', (_event, id: string) => {
const ext = getExtension(id);
return ext ? serializeExtensionInfo(ext) : null;
});
// Get a specific extension by ID
ipcMain.handle("extensions:get", (_event, id: string) => {
const ext = getExtension(id);
return ext ? serializeExtensionInfo(ext) : null;
});
// Enable an extension
ipcMain.handle('extensions:enable', async (_event, id: string) => {
return setExtensionStatus(id, 'active');
});
// Enable an extension
ipcMain.handle("extensions:enable", async (_event, id: string) => {
return setExtensionStatus(id, "active");
});
// Disable an extension
ipcMain.handle('extensions:disable', async (_event, id: string) => {
return setExtensionStatus(id, 'disabled');
});
// Disable an extension
ipcMain.handle("extensions:disable", async (_event, id: string) => {
return setExtensionStatus(id, "disabled");
});
// Install an extension from a folder picker
ipcMain.handle('extensions:install-from-folder', async (event) => {
const window = BrowserWindow.fromWebContents(event.sender);
const result = await dialog.showOpenDialog(window!, {
title: 'Select Extension Folder',
properties: ['openDirectory'],
message: 'Select a folder containing a recordly-extension.json manifest',
});
// Install an extension from a folder picker
ipcMain.handle("extensions:install-from-folder", async (event) => {
const window = BrowserWindow.fromWebContents(event.sender);
const result = await dialog.showOpenDialog(window!, {
title: "Select Extension Folder",
properties: ["openDirectory"],
message: "Select a folder containing a recordly-extension.json manifest",
});
if (result.canceled || result.filePaths.length === 0) {
return { success: false, reason: 'cancelled' };
}
if (result.canceled || result.filePaths.length === 0) {
return { success: false, reason: "cancelled" };
}
const info = await installExtensionFromPath(result.filePaths[0]);
if (!info) {
return { success: false, reason: 'Invalid extension: missing or invalid recordly-extension.json' };
}
const info = await installExtensionFromPath(result.filePaths[0]);
if (!info) {
return {
success: false,
reason: "Invalid extension: missing or invalid recordly-extension.json",
};
}
return { success: true, extension: serializeExtensionInfo(info) };
});
return { success: true, extension: serializeExtensionInfo(info) };
});
// Uninstall an extension
ipcMain.handle('extensions:uninstall', async (_event, id: string) => {
const success = await uninstallExtension(id);
return { success };
});
// Uninstall an extension
ipcMain.handle("extensions:uninstall", async (_event, id: string) => {
const success = await uninstallExtension(id);
return { success };
});
// Get extensions directory path
ipcMain.handle('extensions:get-directory', () => {
return getExtensionsDirectory();
});
// Get extensions directory path
ipcMain.handle("extensions:get-directory", () => {
return getExtensionsDirectory();
});
// Open extensions directory in file manager
ipcMain.handle('extensions:open-directory', async () => {
const dir = getExtensionsDirectory();
await shell.openPath(dir);
return { success: true };
});
// Open extensions directory in file manager
ipcMain.handle("extensions:open-directory", async () => {
const dir = getExtensionsDirectory();
await shell.openPath(dir);
return { success: true };
});
// ── Marketplace ─────────────────────────────────────────────────────
// ── Marketplace ─────────────────────────────────────────────────────
// Search/browse marketplace
ipcMain.handle('extensions:marketplace-search', async (_event, params: {
query?: string;
tags?: string[];
sort?: 'popular' | 'recent' | 'rating';
page?: number;
pageSize?: number;
}) => {
try {
return await searchMarketplace(params);
} catch (err: any) {
return { extensions: [], total: 0, page: 1, pageSize: 20, error: err.message };
}
});
// Search/browse marketplace
ipcMain.handle(
"extensions:marketplace-search",
async (
_event,
params: {
query?: string;
tags?: string[];
sort?: "popular" | "recent" | "rating";
page?: number;
pageSize?: number;
},
) => {
try {
return await searchMarketplace(params);
} catch (err: unknown) {
return {
extensions: [],
total: 0,
page: 1,
pageSize: 20,
error: err instanceof Error ? err.message : String(err),
};
}
},
);
// Get a specific marketplace extension
ipcMain.handle('extensions:marketplace-get', async (_event, id: string) => {
return getMarketplaceExtension(id);
});
// Get a specific marketplace extension
ipcMain.handle("extensions:marketplace-get", async (_event, id: string) => {
return getMarketplaceExtension(id);
});
// Download and install a marketplace extension
ipcMain.handle('extensions:marketplace-install', async (_event, extensionId: string, downloadUrl: string) => {
return downloadAndInstallExtension(extensionId, downloadUrl);
});
// Download and install a marketplace extension
ipcMain.handle(
"extensions:marketplace-install",
async (_event, extensionId: string, downloadUrl: string) => {
return downloadAndInstallExtension(extensionId, downloadUrl);
},
);
// Submit an extension for marketplace review
ipcMain.handle('extensions:marketplace-submit', async (_event, extensionId: string) => {
return submitExtensionForReview(extensionId);
});
// Submit an extension for marketplace review
ipcMain.handle("extensions:marketplace-submit", async (_event, extensionId: string) => {
return submitExtensionForReview(extensionId);
});
// ── Admin Review System ─────────────────────────────────────────────
// ── Admin Review System ─────────────────────────────────────────────
// Fetch pending reviews (admin only)
ipcMain.handle('extensions:reviews-list', async (_event, params: {
status?: MarketplaceReviewStatus;
page?: number;
pageSize?: number;
}) => {
try {
return await fetchPendingReviews(params);
} catch (err: any) {
return { reviews: [], total: 0, error: err.message };
}
});
// Fetch pending reviews (admin only)
ipcMain.handle(
"extensions:reviews-list",
async (
_event,
params: {
status?: MarketplaceReviewStatus;
page?: number;
pageSize?: number;
},
) => {
try {
return await fetchPendingReviews(params);
} catch (err: unknown) {
return {
reviews: [],
total: 0,
error: err instanceof Error ? err.message : String(err),
};
}
},
);
// Update review status (admin only)
ipcMain.handle('extensions:review-update', async (_event, reviewId: string, status: MarketplaceReviewStatus, notes?: string) => {
return updateReviewStatus(reviewId, status, notes);
});
// Update review status (admin only)
ipcMain.handle(
"extensions:review-update",
async (_event, reviewId: string, status: MarketplaceReviewStatus, notes?: string) => {
return updateReviewStatus(reviewId, status, notes);
},
);
}
+29 -30
View File
@@ -1,31 +1,30 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src", "electron"],
"exclude": ["**/*.test.ts", "**/*.test.tsx"],
"references": [{ "path": "./tsconfig.node.json" }]
}
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src", "electron"],
"exclude": ["**/*.test.ts", "**/*.test.tsx"],
"references": [{ "path": "./tsconfig.node.json" }]
}
+16 -17
View File
@@ -1,19 +1,18 @@
import { defineConfig } from 'vitest/config'
import path from 'node:path'
import path from "node:path";
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
globals: true,
environment: 'node',
include: [
'src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}',
'electron/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}',
],
},
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
})
test: {
globals: true,
environment: "node",
include: [
"src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}",
"electron/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}",
],
},
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
},
},
});