Browse Source

fix swagger

Nostr-Signature: c0eb40be64306e1b11eba642ad357fd877776f50c8e64867cff845b92851c60e 573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc 194bedf752e25da9924bcf16b55eec0b29ae5da8bcd3f2a646e072f08d2d8f499269d42fafe6c056effb22840be0101c243aa1852b41899a73b242e6d6ad2932
main
Silberengel 3 weeks ago
parent
commit
2ff3829c99
  1. 1
      nostr/commit-signatures.jsonl
  2. 34
      package-lock.json
  3. 147
      scripts/sync-cli.sh
  4. 7
      src/lib/services/messaging/event-forwarder.ts
  5. 5
      src/routes/api-docs/+page.svelte
  6. 11
      src/routes/api/openapi.json/+server.ts
  7. 1132
      src/routes/api/openapi.json/openapi.json
  8. 5
      src/routes/api/repos/[npub]/[repo]/branches/+server.ts
  9. 3
      src/routes/api/repos/[npub]/[repo]/commits/+server.ts
  10. 3
      src/routes/api/repos/[npub]/[repo]/highlights/+server.ts
  11. 3
      src/routes/api/repos/[npub]/[repo]/issues/+server.ts
  12. 3
      src/routes/api/repos/[npub]/[repo]/prs/+server.ts
  13. 3
      src/routes/api/repos/[npub]/[repo]/tree/+server.ts
  14. 10
      src/routes/users/[npub]/+page.svelte

1
nostr/commit-signatures.jsonl

@ -2,3 +2,4 @@ @@ -2,3 +2,4 @@
{"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1771497680,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","validate signatures"]],"content":"Signed commit: validate signatures","id":"47edd2e8cbea27854a429202ddfb3fde3531a355276c619258bc90c4d6ce54cc","sig":"a941abf1d2c8e7dae4d5b4d6424c2e5394b05c98898d88b7acc1501cd6d8d3d13aea8be8d797dcb0701f752a32bf72a3b02f3c814707e10ed18d6d24f11d8ae0"}
{"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1771502215,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","added push-all to the cli\nimplement black theme\nimplement swagger API docs"]],"content":"Signed commit: added push-all to the cli\nimplement black theme\nimplement swagger API docs","id":"c15ce3d2f1ae613492802533a7e71b96df919a2ff52d501630c6ee64abf6a718","sig":"ba72d348528a2846c5e44474af821e79fcdb377caa0d905ae7e7fc9115b77ea92f65325a8f0000f83467983068f643ecf3beaca784666d361a8883160ae3a936"}
{"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1771513666,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","setup separate repos"]],"content":"Signed commit: setup separate repos","id":"62fa7c667e07791d898d0af8971165a57df5a061585e4a71447e52f7444dc687","sig":"25ef4575b03248381920985338e0ff4605f0af3fcaf8615d7906e3e116e3fbb64de3f3927f511fd45340e7dbdc4a2c3ea7fa150e5e9c75a6b5880cecaa4d2851"}
{"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1771516332,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","security fixes"]],"content":"Signed commit: security fixes","id":"a16b9538d6ce6ce2f1030042a4106534e2af1583642315893cc56d9f2e7cd385","sig":"0be95c5f2d720c008b52a1d38cef9952b1a615ecd3ef34b5b373266a2afb880e30347d3ee467b4ea42eca4a0e57808f98795ada878357ad39ca1a3063d6b6a22"}

34
package-lock.json generated

@ -8,6 +8,9 @@ @@ -8,6 +8,9 @@
"name": "gitrepublic-web",
"version": "0.1.0",
"license": "MIT",
"workspaces": [
"gitrepublic-cli"
],
"dependencies": {
"@codemirror/autocomplete": "^6.20.0",
"@codemirror/basic-setup": "^0.20.0",
@ -48,6 +51,33 @@ @@ -48,6 +51,33 @@
"vite": "^5.4.11"
}
},
"gitrepublic-cli": {
"version": "1.0.0",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"nostr-tools": "^2.22.1"
},
"bin": {
"gitrep": "scripts/git-wrapper.js",
"gitrep-api": "scripts/gitrepublic.js",
"gitrep-commit": "scripts/git-commit-msg-hook.js",
"gitrep-cred": "scripts/git-credential-nostr.js",
"gitrep-path": "scripts/get-path.js",
"gitrep-setup": "scripts/setup.js",
"gitrep-uninstall": "scripts/uninstall.js",
"gitrepublic": "scripts/git-wrapper.js",
"gitrepublic-api": "scripts/gitrepublic.js",
"gitrepublic-commit-hook": "scripts/git-commit-msg-hook.js",
"gitrepublic-credential": "scripts/git-credential-nostr.js",
"gitrepublic-path": "scripts/get-path.js",
"gitrepublic-setup": "scripts/setup.js",
"gitrepublic-uninstall": "scripts/uninstall.js"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@asciidoctor/cli": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@asciidoctor/cli/-/cli-4.0.0.tgz",
@ -3237,6 +3267,10 @@ @@ -3237,6 +3267,10 @@
"node": ">= 0.4"
}
},
"node_modules/gitrepublic-cli": {
"resolved": "gitrepublic-cli",
"link": true
},
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",

147
scripts/sync-cli.sh

@ -2,14 +2,13 @@ @@ -2,14 +2,13 @@
# Sync gitrepublic-cli to a separate repository
# Usage: ./scripts/sync-cli.sh [path-to-separate-repo]
set -e
set -uo pipefail # Don't exit on error (-e removed) so we can handle push failures gracefully
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
CLI_DIR="$REPO_ROOT/gitrepublic-cli"
# Default separate repo path (can be overridden)
# Use the same parent directory as the monorepo
# Default separate repo path
MONOREPO_PARENT="$(dirname "$REPO_ROOT")"
SEPARATE_REPO="${1:-$MONOREPO_PARENT/gitrepublic-cli}"
@ -26,41 +25,137 @@ if [ ! -d "$SEPARATE_REPO" ]; then @@ -26,41 +25,137 @@ if [ ! -d "$SEPARATE_REPO" ]; then
mkdir -p "$SEPARATE_REPO"
cd "$SEPARATE_REPO"
git init
git remote add origin https://github.com/silberengel/gitrepublic-cli.git 2>/dev/null || true
# Don't add remote automatically - let user configure it
echo "ℹ Repository created. Configure remotes with:"
echo " git remote add origin <your-repo-url>"
fi
# Copy files (excluding node_modules, .git, etc.)
cd "$SEPARATE_REPO"
# Change to separate repo directory
cd "$SEPARATE_REPO" || exit 1
# Copy files using rsync
rsync -av --delete \
--exclude='node_modules' \
--exclude='.git' \
--exclude='package-lock.json' \
--exclude='nostr/' \
--exclude='*.log' \
--exclude='.DS_Store' \
"$CLI_DIR/" .
# Commit and push if there are changes
# Stage all changes
git add -A
# Check if there are any changes to commit
if [ -n "$(git status --porcelain)" ]; then
git add -A
git commit -m "Sync from gitrepublic-web monorepo" || echo "No changes to commit"
# Check if remote exists, if not provide instructions
if git remote get-url origin >/dev/null 2>&1; then
# Try to push to main or master branch
if git push origin main 2>/dev/null || git push origin master 2>/dev/null; then
echo "✅ Synced and pushed to remote repository"
echo "Changes detected, committing..."
COMMIT_MSG="Sync from gitrepublic-web monorepo - $(date '+%Y-%m-%d %H:%M:%S')"
git commit -m "$COMMIT_MSG"
echo "✅ Committed changes"
else
echo "✅ No changes to commit (files are up to date)"
fi
# Get all remotes and push to each one
REMOTES="$(git remote)"
CURRENT_BRANCH="$(git branch --show-current || echo 'master')"
if [ -z "$REMOTES" ]; then
echo "ℹ No remotes configured"
exit 0
fi
echo ""
echo "Pushing to remotes..."
# Fetch from all remotes first
for remote in $REMOTES; do
echo "Fetching from $remote..."
git fetch "$remote" 2>/dev/null || true
done
# Check if remotes have commits local doesn't have (diverged history)
echo ""
echo "Checking for diverged history..."
for remote in $REMOTES; do
REMOTE_BRANCH="${remote}/${CURRENT_BRANCH}"
if git rev-parse --verify "$REMOTE_BRANCH" >/dev/null 2>&1; then
BEHIND=$(git rev-list --count HEAD.."$REMOTE_BRANCH" 2>/dev/null || echo "0")
AHEAD=$(git rev-list --count "$REMOTE_BRANCH"..HEAD 2>/dev/null || echo "0")
if [ "$BEHIND" -gt 0 ]; then
echo " $remote has $BEHIND commit(s) that local doesn't have"
echo " Local has $AHEAD commit(s) that $remote doesn't have"
echo " Histories have diverged - need to merge or rebase"
fi
fi
done
# Push to all remotes
for remote in $REMOTES; do
echo ""
echo "Pushing to $remote ($CURRENT_BRANCH)..."
# Check if local is ahead of remote
REMOTE_BRANCH="${remote}/${CURRENT_BRANCH}"
if git rev-parse --verify "$REMOTE_BRANCH" >/dev/null 2>&1; then
AHEAD=$(git rev-list --count "$REMOTE_BRANCH"..HEAD 2>/dev/null || echo "0")
if [ "$AHEAD" -gt 0 ]; then
echo " Local is $AHEAD commit(s) ahead of $remote"
fi
fi
# Try to push current branch (master) - don't use timeout as it might interfere with SSH
PUSH_OUTPUT=$(git push "$remote" "$CURRENT_BRANCH" 2>&1)
PUSH_EXIT=$?
if [ $PUSH_EXIT -eq 0 ]; then
# Check if output says "already up to date"
if echo "$PUSH_OUTPUT" | grep -qi "already up to date\|Everything up-to-date"; then
echo " $remote is already up to date"
else
echo "⚠ Synced locally, but push failed. Check remote configuration."
echo "✅ Successfully pushed to $remote"
echo "$PUSH_OUTPUT" | grep -v "^$" | head -3
fi
else
echo "✅ Synced to local repository"
echo "ℹ To push to a remote, run:"
echo " cd $SEPARATE_REPO"
echo " git remote add origin <your-repo-url>"
echo " git branch -M main # if needed"
echo " git push -u origin main"
# Push failed - show the full error
echo " Push to $remote failed:"
echo "$PUSH_OUTPUT" | sed 's/^/ /'
# Check if it's a non-fast-forward (diverged history)
if echo "$PUSH_OUTPUT" | grep -qi "non-fast-forward\|behind.*remote\|diverged"; then
REMOTE_BRANCH="${remote}/${CURRENT_BRANCH}"
BEHIND=$(git rev-list --count HEAD.."$REMOTE_BRANCH" 2>/dev/null || echo "0")
AHEAD=$(git rev-list --count "$REMOTE_BRANCH"..HEAD 2>/dev/null || echo "0")
if [ "$BEHIND" -gt 0 ]; then
echo ""
echo " Histories have diverged:"
echo " - Remote has $BEHIND commit(s) you don't have"
echo " - You have $AHEAD commit(s) remote doesn't have"
echo ""
echo " For sync script, attempting force push to overwrite remote with local..."
echo " (This makes remote match the monorepo - monorepo is source of truth)"
# Force push to make remote match local (monorepo is source of truth)
if FORCE_PUSH_OUTPUT=$(git push -f "$remote" "$CURRENT_BRANCH" 2>&1); then
echo "✅ Successfully force-pushed to $remote"
echo "$FORCE_PUSH_OUTPUT" | grep -v "^$" | head -2 | sed 's/^/ /'
else
echo "⚠ Force push also failed:"
echo "$FORCE_PUSH_OUTPUT" | sed 's/^/ /'
fi
fi
elif echo "$PUSH_OUTPUT" | grep -qi "refspec\|branch.*not found\|no such branch"; then
# Branch doesn't exist on remote - set upstream
echo " Attempting to set upstream and push..."
if git push -u "$remote" "$CURRENT_BRANCH" 2>&1; then
echo "✅ Successfully pushed to $remote (with upstream set)"
else
echo " Still failed after setting upstream"
fi
fi
fi
else
echo "✅ No changes to sync"
fi
done
echo "Done!"
echo ""
echo "✅ Sync complete!"

7
src/lib/services/messaging/event-forwarder.ts

@ -18,9 +18,10 @@ async function getPreferencesLazy() { @@ -18,9 +18,10 @@ async function getPreferencesLazy() {
return null;
}
if (!getPreferences) {
// Use dynamic path construction to prevent Vite from statically analyzing the import
const storagePath = './preferences-storage' + '.server.js';
const module = await import(storagePath);
// Use static import path with vite-ignore to prevent static analysis
// This is intentional - we only want to import this server-side
// @ts-ignore - Dynamic import for server-side only code
const module = await import(/* @vite-ignore */ './preferences-storage.server.js');
getPreferences = module.getPreferences;
}
return getPreferences;

5
src/routes/api-docs/+page.svelte

@ -29,14 +29,15 @@ @@ -29,14 +29,15 @@
// @ts-ignore
window.SwaggerUIBundle.presets.standalone
],
layout: 'StandaloneLayout',
deepLinking: true,
deepLinking: false, // Disabled to avoid conflict with SvelteKit's router
displayRequestDuration: true,
tryItOutEnabled: true,
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
validatorUrl: null,
docExpansion: 'list',
filter: true,
defaultModelsExpandDepth: 1,
defaultModelExpandDepth: 1,
showExtensions: true,
showCommonExtensions: true
});

11
src/routes/api/openapi.json/+server.ts

@ -1,8 +1,17 @@ @@ -1,8 +1,17 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import openApiSpec from './openapi.json';
import { readFileSync } from 'fs';
import { join } from 'path';
import { fileURLToPath } from 'url';
// Read the file dynamically to avoid Vite caching issues
const __dirname = fileURLToPath(new URL('.', import.meta.url));
const specPath = join(__dirname, 'openapi.json');
export const GET: RequestHandler = async () => {
// Read file fresh on each request to avoid cache issues during development
const openApiSpec = JSON.parse(readFileSync(specPath, 'utf-8'));
return json(openApiSpec, {
headers: {
'Content-Type': 'application/json',

1132
src/routes/api/openapi.json/openapi.json

File diff suppressed because it is too large Load Diff

5
src/routes/api/repos/[npub]/[repo]/branches/+server.ts

@ -16,6 +16,7 @@ import { repoCache, RepoCache } from '$lib/services/git/repo-cache.js'; @@ -16,6 +16,7 @@ import { repoCache, RepoCache } from '$lib/services/git/repo-cache.js';
import { DEFAULT_NOSTR_RELAYS, DEFAULT_NOSTR_SEARCH_RELAYS } from '$lib/config.js';
import { NostrClient } from '$lib/services/nostr/nostr-client.js';
import { eventCache } from '$lib/services/nostr/event-cache.js';
import logger from '$lib/services/logger.js';
const repoRoot = typeof process !== 'undefined' && process.env?.GIT_REPO_ROOT
? process.env.GIT_REPO_ROOT
@ -86,7 +87,7 @@ export const GET: RequestHandler = createRepoGetHandler( @@ -86,7 +87,7 @@ export const GET: RequestHandler = createRepoGetHandler(
repoCache.delete(RepoCache.repoExistsKey(context.npub, context.repo));
} else {
// Log the error for debugging
console.error('[Branches] Error fetching repository:', err);
logger.error({ error: err, npub: context.npub, repo: context.repo }, '[Branches] Error fetching repository');
// If fetching fails, return 404 with more context
const errorMessage = err instanceof Error ? err.message : 'Repository not found';
throw handleNotFoundError(
@ -110,7 +111,7 @@ export const GET: RequestHandler = createRepoGetHandler( @@ -110,7 +111,7 @@ export const GET: RequestHandler = createRepoGetHandler(
return json(branches);
} catch (err) {
// Log the actual error for debugging
console.error('[Branches] Error getting branches:', err);
logger.error({ error: err, npub: context.npub, repo: context.repo }, '[Branches] Error getting branches');
// Check if it's a "not found" error
if (err instanceof Error && err.message.includes('not found')) {
throw handleNotFoundError(

3
src/routes/api/repos/[npub]/[repo]/commits/+server.ts

@ -12,6 +12,7 @@ import { KIND } from '$lib/types/nostr.js'; @@ -12,6 +12,7 @@ import { KIND } from '$lib/types/nostr.js';
import { join } from 'path';
import { existsSync } from 'fs';
import { repoCache, RepoCache } from '$lib/services/git/repo-cache.js';
import logger from '$lib/services/logger.js';
const repoRoot = typeof process !== 'undefined' && process.env?.GIT_REPO_ROOT
? process.env.GIT_REPO_ROOT
@ -96,7 +97,7 @@ export const GET: RequestHandler = createRepoGetHandler( @@ -96,7 +97,7 @@ export const GET: RequestHandler = createRepoGetHandler(
return json(commits);
} catch (err) {
// Log the actual error for debugging
console.error('[Commits] Error getting commit history:', err);
logger.error({ error: err, npub: context.npub, repo: context.repo }, '[Commits] Error getting commit history');
// Check if it's a "not found" error
if (err instanceof Error && err.message.includes('not found')) {
throw handleNotFoundError(

3
src/routes/api/repos/[npub]/[repo]/highlights/+server.ts

@ -14,6 +14,7 @@ import type { RepoRequestContext, RequestEvent } from '$lib/utils/api-context.js @@ -14,6 +14,7 @@ import type { RepoRequestContext, RequestEvent } from '$lib/utils/api-context.js
import { handleApiError, handleValidationError } from '$lib/utils/error-handler.js';
import { decodeNpubToHex } from '$lib/utils/npub-utils.js';
import { forwardEventIfEnabled } from '$lib/services/messaging/event-forwarder.js';
import logger from '$lib/services/logger.js';
/**
* GET - Get highlights for a pull request
@ -93,7 +94,7 @@ export const POST: RequestHandler = withRepoValidation( @@ -93,7 +94,7 @@ export const POST: RequestHandler = withRepoValidation(
forwardEventIfEnabled(highlightEvent as NostrEvent, userPubkeyHex)
.catch(err => {
// Log but don't fail the request - forwarding is optional
console.error('Failed to forward event to messaging platforms:', err);
logger.warn({ error: err, npub: repoContext.npub, repo: repoContext.repo }, 'Failed to forward event to messaging platforms');
});
}

3
src/routes/api/repos/[npub]/[repo]/issues/+server.ts

@ -10,6 +10,7 @@ import type { RepoRequestContext, RequestEvent } from '$lib/utils/api-context.js @@ -10,6 +10,7 @@ import type { RepoRequestContext, RequestEvent } from '$lib/utils/api-context.js
import { handleValidationError, handleApiError } from '$lib/utils/error-handler.js';
import { DEFAULT_NOSTR_RELAYS } from '$lib/config.js';
import { forwardEventIfEnabled } from '$lib/services/messaging/event-forwarder.js';
import logger from '$lib/services/logger.js';
export const GET: RequestHandler = createRepoGetHandler(
async (context: RepoRequestContext) => {
@ -45,7 +46,7 @@ export const POST: RequestHandler = withRepoValidation( @@ -45,7 +46,7 @@ export const POST: RequestHandler = withRepoValidation(
forwardEventIfEnabled(issueEvent, requestContext.userPubkeyHex)
.catch(err => {
// Log but don't fail the request - forwarding is optional
console.error('Failed to forward event to messaging platforms:', err);
logger.warn({ error: err, npub: repoContext.npub, repo: repoContext.repo }, 'Failed to forward event to messaging platforms');
});
}

3
src/routes/api/repos/[npub]/[repo]/prs/+server.ts

@ -11,6 +11,7 @@ import type { RepoRequestContext, RequestEvent } from '$lib/utils/api-context.js @@ -11,6 +11,7 @@ import type { RepoRequestContext, RequestEvent } from '$lib/utils/api-context.js
import { handleValidationError, handleApiError } from '$lib/utils/error-handler.js';
import { DEFAULT_NOSTR_RELAYS } from '$lib/config.js';
import { forwardEventIfEnabled } from '$lib/services/messaging/event-forwarder.js';
import logger from '$lib/services/logger.js';
export const GET: RequestHandler = createRepoGetHandler(
async (context: RepoRequestContext) => {
@ -46,7 +47,7 @@ export const POST: RequestHandler = withRepoValidation( @@ -46,7 +47,7 @@ export const POST: RequestHandler = withRepoValidation(
forwardEventIfEnabled(prEvent, requestContext.userPubkeyHex)
.catch(err => {
// Log but don't fail the request - forwarding is optional
console.error('Failed to forward event to messaging platforms:', err);
logger.warn({ error: err, npub: repoContext.npub, repo: repoContext.repo }, 'Failed to forward event to messaging platforms');
});
}

3
src/routes/api/repos/[npub]/[repo]/tree/+server.ts

@ -12,6 +12,7 @@ import { KIND } from '$lib/types/nostr.js'; @@ -12,6 +12,7 @@ import { KIND } from '$lib/types/nostr.js';
import { join } from 'path';
import { existsSync } from 'fs';
import { repoCache, RepoCache } from '$lib/services/git/repo-cache.js';
import logger from '$lib/services/logger.js';
const repoRoot = typeof process !== 'undefined' && process.env?.GIT_REPO_ROOT
? process.env.GIT_REPO_ROOT
@ -105,7 +106,7 @@ export const GET: RequestHandler = createRepoGetHandler( @@ -105,7 +106,7 @@ export const GET: RequestHandler = createRepoGetHandler(
return json(files);
} catch (err) {
// Log the actual error for debugging
console.error('[Tree] Error listing files:', err);
logger.error({ error: err, npub: context.npub, repo: context.repo }, '[Tree] Error listing files');
// Check if it's a "not found" error
if (err instanceof Error && err.message.includes('not found')) {
throw handleNotFoundError(

10
src/routes/users/[npub]/+page.svelte

@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
import { PublicMessagesService, type PublicMessage } from '$lib/services/nostr/public-messages-service.js';
import { getUserRelays } from '$lib/services/nostr/user-relays.js';
import UserBadge from '$lib/components/UserBadge.svelte';
import { forwardEventIfEnabled } from '$lib/services/messaging/event-forwarder.js';
// forwardEventIfEnabled is server-side only - import dynamically if needed
import { userStore } from '$lib/stores/user-store.js';
const npub = ($page.params as { npub?: string }).npub || '';
@ -256,12 +256,8 @@ @@ -256,12 +256,8 @@
}
// Forward to messaging platforms if user has unlimited access and preferences configured
if (result.success.length > 0 && viewerPubkeyHex) {
forwardEventIfEnabled(signedEvent, viewerPubkeyHex)
.catch(err => {
console.error('Failed to forward message to messaging platforms:', err);
});
}
// This is done server-side via API endpoints, not from client
// The server-side API endpoints (issues, prs, highlights) handle forwarding automatically
// Reload messages
await loadMessages();

Loading…
Cancel
Save