diff --git a/src/app.css b/src/app.css index c215d41..8aaaf69 100644 --- a/src/app.css +++ b/src/app.css @@ -1,3 +1,6 @@ +/* Import fonts - IBM Plex Serif for classic Roman feel with modern tech aesthetic */ +@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Serif:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&family=IBM+Plex+Mono:wght@400;500;600;700&display=swap'); + /* GitRepublic Theme - Light/Dark Mode with Royal Plum Palette */ :root { @@ -78,9 +81,6 @@ --warning-text: #fbbf24; } -/* Import fonts - IBM Plex Serif for classic Roman feel with modern tech aesthetic */ -@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Serif:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&family=IBM+Plex+Mono:wght@400;500;600;700&display=swap'); - /* Base styles */ * { box-sizing: border-box; diff --git a/src/lib/services/git/commit-signer.ts b/src/lib/services/git/commit-signer.ts index c298973..da3b679 100644 --- a/src/lib/services/git/commit-signer.ts +++ b/src/lib/services/git/commit-signer.ts @@ -6,7 +6,7 @@ * - Direct nsec/hex keys (for server-side signing) */ -import { nip19, getPublicKey, finalizeEvent, getEventHash } from 'nostr-tools'; +import { nip19, getPublicKey, finalizeEvent } from 'nostr-tools'; import { createHash } from 'crypto'; import type { NostrEvent } from '../../types/nostr.js'; import { KIND } from '../../types/nostr.js'; diff --git a/src/lib/services/git/repo-manager.ts b/src/lib/services/git/repo-manager.ts index a6e11b4..c9c03a7 100644 --- a/src/lib/services/git/repo-manager.ts +++ b/src/lib/services/git/repo-manager.ts @@ -312,7 +312,7 @@ export class RepoManager { ); commitMessage = signedMessage; } catch (err) { - logger.warn({ error: err, repoPath: repoPath.fullPath }, 'Failed to sign initial commit'); + logger.warn({ error: err, repoPath }, 'Failed to sign initial commit'); // Continue without signature if signing fails } } @@ -332,7 +332,7 @@ export class RepoManager { // Clean up await rm(workDir, { recursive: true, force: true }); } catch (error) { - logger.error({ error, repoPath: repoPath.fullPath }, 'Failed to create verification file'); + logger.error({ error, repoPath }, 'Failed to create verification file'); // Don't throw - verification file creation is important but shouldn't block provisioning } } diff --git a/src/lib/services/nostr/maintainer-service.ts b/src/lib/services/nostr/maintainer-service.ts index 3545fa1..89c74aa 100644 --- a/src/lib/services/nostr/maintainer-service.ts +++ b/src/lib/services/nostr/maintainer-service.ts @@ -110,7 +110,7 @@ export class MaintainerService { this.cache.set(cacheKey, { ...result, timestamp: Date.now() }); return result; } catch (error) { - logger.error({ error, ownerPubkey, repoName }, 'Error fetching maintainers'); + logger.error({ error, repoOwnerPubkey, repoId }, 'Error fetching maintainers'); // Fallback: only owner is maintainer, repo is public by default const result = { owner: repoOwnerPubkey, maintainers: [repoOwnerPubkey], isPrivate: false }; this.cache.set(cacheKey, { ...result, timestamp: Date.now() }); diff --git a/src/lib/services/nostr/nostr-client.ts b/src/lib/services/nostr/nostr-client.ts index f19cee4..c71afc2 100644 --- a/src/lib/services/nostr/nostr-client.ts +++ b/src/lib/services/nostr/nostr-client.ts @@ -3,20 +3,26 @@ */ import type { NostrEvent, NostrFilter } from '../../types/nostr.js'; -import { createRequire } from 'module'; import logger from '../logger.js'; // Polyfill WebSocket for Node.js environments (lazy initialization) let wsPolyfillInitialized = false; -function initializeWebSocketPolyfill() { +async function initializeWebSocketPolyfill() { if (wsPolyfillInitialized) return; if (typeof global === 'undefined' || typeof global.WebSocket !== 'undefined') { wsPolyfillInitialized = true; return; } + // Only run in Node.js/server environment + if (typeof process === 'undefined' || !process.versions?.node) { + wsPolyfillInitialized = true; + return; + } + try { - // Use createRequire for ES modules compatibility + // Dynamic import to avoid bundling for browser + const { createRequire } = await import('module'); const requireFunc = createRequire(import.meta.url); const WebSocketImpl = requireFunc('ws'); global.WebSocket = WebSocketImpl as any; @@ -28,9 +34,11 @@ function initializeWebSocketPolyfill() { } } -// Initialize on module load if in Node.js +// Initialize on module load if in Node.js (fire and forget) if (typeof process !== 'undefined' && process.versions?.node) { - initializeWebSocketPolyfill(); + initializeWebSocketPolyfill().catch(() => { + // Ignore errors during initialization + }); } export class NostrClient { @@ -66,7 +74,7 @@ export class NostrClient { private async fetchFromRelay(relay: string, filters: NostrFilter[]): Promise { // Ensure WebSocket polyfill is initialized - initializeWebSocketPolyfill(); + await initializeWebSocketPolyfill(); return new Promise((resolve, reject) => { const ws = new WebSocket(relay); @@ -164,7 +172,7 @@ export class NostrClient { private async publishToRelay(relay: string, nostrEvent: NostrEvent): Promise { // Ensure WebSocket polyfill is initialized - initializeWebSocketPolyfill(); + await initializeWebSocketPolyfill(); return new Promise((resolve, reject) => { const ws = new WebSocket(relay); diff --git a/src/lib/services/nostr/ownership-transfer-service.ts b/src/lib/services/nostr/ownership-transfer-service.ts index 95509cd..4167c16 100644 --- a/src/lib/services/nostr/ownership-transfer-service.ts +++ b/src/lib/services/nostr/ownership-transfer-service.ts @@ -101,7 +101,7 @@ export class OwnershipTransferService { this.cache.set(cacheKey, { owner: currentOwner, timestamp: Date.now() }); return currentOwner; } catch (error) { - logger.error({ error, originalOwnerPubkey, repoName }, 'Error fetching ownership transfers'); + logger.error({ error, originalOwnerPubkey, repoId }, 'Error fetching ownership transfers'); // Fallback to original owner return originalOwnerPubkey; } @@ -306,7 +306,7 @@ export class OwnershipTransferService { transfers.sort((a, b) => b.timestamp - a.timestamp); return transfers; } catch (error) { - logger.error({ error, ownerPubkey, repoName }, 'Error fetching transfer history'); + logger.error({ error, originalOwnerPubkey, repoId }, 'Error fetching transfer history'); return []; } } diff --git a/src/lib/services/nostr/repo-verification.ts b/src/lib/services/nostr/repo-verification.ts index 057a8aa..15b21a1 100644 --- a/src/lib/services/nostr/repo-verification.ts +++ b/src/lib/services/nostr/repo-verification.ts @@ -3,7 +3,7 @@ * Creates and verifies cryptographic proof linking repo announcements to git repos */ -import { getEventHash, verifyEvent } from 'nostr-tools'; +import { verifyEvent } from 'nostr-tools'; import type { NostrEvent } from '../../types/nostr.js'; import { nip19 } from 'nostr-tools'; diff --git a/src/routes/api/repos/[npub]/[repo]/branches/+server.ts b/src/routes/api/repos/[npub]/[repo]/branches/+server.ts index bb16a0f..760414a 100644 --- a/src/routes/api/repos/[npub]/[repo]/branches/+server.ts +++ b/src/routes/api/repos/[npub]/[repo]/branches/+server.ts @@ -42,9 +42,12 @@ export const POST: RequestHandler = async ({ params, request }: { params: { npub return error(400, 'Missing npub or repo parameter'); } + let branchName: string | undefined; + let fromBranch: string | undefined; + let userPubkey: string | undefined; try { const body = await request.json(); - const { branchName, fromBranch, userPubkey } = body; + ({ branchName, fromBranch, userPubkey } = body); if (!branchName) { return error(400, 'Missing branchName parameter'); diff --git a/src/routes/api/repos/[npub]/[repo]/download/+server.ts b/src/routes/api/repos/[npub]/[repo]/download/+server.ts index 53d44ce..31ea23d 100644 --- a/src/routes/api/repos/[npub]/[repo]/download/+server.ts +++ b/src/routes/api/repos/[npub]/[repo]/download/+server.ts @@ -12,7 +12,6 @@ import { exec } from 'child_process'; import { promisify } from 'util'; import { existsSync, readFileSync } from 'fs'; import { join } from 'path'; -import { createReadStream } from 'fs'; import logger from '$lib/services/logger.js'; const execAsync = promisify(exec); diff --git a/src/routes/api/repos/[npub]/[repo]/tags/+server.ts b/src/routes/api/repos/[npub]/[repo]/tags/+server.ts index f668b2e..ca1c531 100644 --- a/src/routes/api/repos/[npub]/[repo]/tags/+server.ts +++ b/src/routes/api/repos/[npub]/[repo]/tags/+server.ts @@ -50,9 +50,13 @@ export const POST: RequestHandler = async ({ params, request }: { params: { npub return error(400, 'Missing npub or repo parameter'); } + let tagName: string | undefined; + let ref: string | undefined; + let message: string | undefined; + let userPubkey: string | undefined; try { const body = await request.json(); - const { tagName, ref, message, userPubkey } = body; + ({ tagName, ref, message, userPubkey } = body); if (!tagName) { return error(400, 'Missing tagName parameter'); diff --git a/src/routes/api/repos/[npub]/[repo]/tree/+server.ts b/src/routes/api/repos/[npub]/[repo]/tree/+server.ts index fa455f1..1ef8847 100644 --- a/src/routes/api/repos/[npub]/[repo]/tree/+server.ts +++ b/src/routes/api/repos/[npub]/[repo]/tree/+server.ts @@ -50,7 +50,7 @@ export const GET: RequestHandler = async ({ params, url, request }) => { const files = await fileManager.listFiles(npub, repo, ref, path); return json(files); } catch (err) { - logger.error({ error: err, npub, repo, path, branch }, 'Error listing files'); + logger.error({ error: err, npub, repo, path, ref }, 'Error listing files'); return error(500, err instanceof Error ? err.message : 'Failed to list files'); } };