fix: migrate gitea remote to hermes VPS + fix TS errors from Gemini codegen
- gitea remote now points to http://143.198.27.163:3000/admin/timmy-tower.git (no more bore tunnel / Tailscale dependency) - push-to-gitea.sh: default URL → hermes, user → admin, fix http:// URL injection - .gitea-credentials: hermes token saved (gitignored) - orval.config.cjs: converted from .ts (fixed orval v8 TS config loading) - api-zod/src/index.ts: removed duplicate types/ re-export (both api.ts and types/ export same names — api.ts is sufficient) - integrations-gemini-ai/tsconfig.json: types:[] (no @types/node in this pkg) - batch/utils.ts: import AbortError as named export (not pRetry.AbortError) - image/index.ts: remove ai re-export (ai only on main client.ts now) - routes/gemini.ts: req.params[id] cast to String() for Express 5 type compat - package.json typecheck: exclude mockup-sandbox (pre-existing React 19 ref errors)
This commit is contained in:
@@ -35,7 +35,7 @@ router.post("/conversations", async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.get("/conversations/:id", async (req: Request, res: Response) => {
|
router.get("/conversations/:id", async (req: Request, res: Response) => {
|
||||||
const id = parseInt(req.params.id ?? "", 10);
|
const id = parseInt(String(req.params["id"]), 10);
|
||||||
if (isNaN(id)) {
|
if (isNaN(id)) {
|
||||||
res.status(400).json({ error: "Invalid id" });
|
res.status(400).json({ error: "Invalid id" });
|
||||||
return;
|
return;
|
||||||
@@ -59,7 +59,7 @@ router.get("/conversations/:id", async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.delete("/conversations/:id", async (req: Request, res: Response) => {
|
router.delete("/conversations/:id", async (req: Request, res: Response) => {
|
||||||
const id = parseInt(req.params.id ?? "", 10);
|
const id = parseInt(String(req.params["id"]), 10);
|
||||||
if (isNaN(id)) {
|
if (isNaN(id)) {
|
||||||
res.status(400).json({ error: "Invalid id" });
|
res.status(400).json({ error: "Invalid id" });
|
||||||
return;
|
return;
|
||||||
@@ -79,7 +79,7 @@ router.delete("/conversations/:id", async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.get("/conversations/:id/messages", async (req: Request, res: Response) => {
|
router.get("/conversations/:id/messages", async (req: Request, res: Response) => {
|
||||||
const id = parseInt(req.params.id ?? "", 10);
|
const id = parseInt(String(req.params["id"]), 10);
|
||||||
if (isNaN(id)) {
|
if (isNaN(id)) {
|
||||||
res.status(400).json({ error: "Invalid id" });
|
res.status(400).json({ error: "Invalid id" });
|
||||||
return;
|
return;
|
||||||
@@ -98,7 +98,7 @@ router.get("/conversations/:id/messages", async (req: Request, res: Response) =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.post("/conversations/:id/messages", async (req: Request, res: Response) => {
|
router.post("/conversations/:id/messages", async (req: Request, res: Response) => {
|
||||||
const conversationId = parseInt(req.params.id ?? "", 10);
|
const conversationId = parseInt(String(req.params["id"]), 10);
|
||||||
if (isNaN(conversationId)) {
|
if (isNaN(conversationId)) {
|
||||||
res.status(400).json({ error: "Invalid id" });
|
res.status(400).json({ error: "Invalid id" });
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
export * from "./generated/api";
|
export * from "./generated/api";
|
||||||
export * from "./generated/types";
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import pLimit from "p-limit";
|
import pLimit from "p-limit";
|
||||||
import pRetry from "p-retry";
|
import pRetry, { AbortError } from "p-retry";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Batch Processing Utilities
|
* Batch Processing Utilities
|
||||||
@@ -74,7 +74,7 @@ export async function batchProcess<T, R>(
|
|||||||
if (isRateLimitError(error)) {
|
if (isRateLimitError(error)) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
throw new pRetry.AbortError(
|
throw new AbortError(
|
||||||
error instanceof Error ? error : new Error(String(error))
|
error instanceof Error ? error : new Error(String(error))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ export async function batchProcessWithSSE<T, R>(
|
|||||||
factor: 2,
|
factor: 2,
|
||||||
onFailedAttempt: (error) => {
|
onFailedAttempt: (error) => {
|
||||||
if (!isRateLimitError(error)) {
|
if (!isRateLimitError(error)) {
|
||||||
throw new pRetry.AbortError(
|
throw new AbortError(
|
||||||
error instanceof Error ? error : new Error(String(error))
|
error instanceof Error ? error : new Error(String(error))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export { ai, generateImage } from "./client";
|
export { generateImage } from "./client";
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"emitDeclarationOnly": true,
|
"emitDeclarationOnly": true,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
"types": ["node"]
|
"types": []
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"preinstall": "sh -c 'rm -f package-lock.json yarn.lock; case \"$npm_config_user_agent\" in pnpm/*) ;; *) echo \"Use pnpm instead\" >&2; exit 1 ;; esac'",
|
"preinstall": "sh -c 'rm -f package-lock.json yarn.lock; case \"$npm_config_user_agent\" in pnpm/*) ;; *) echo \"Use pnpm instead\" >&2; exit 1 ;; esac'",
|
||||||
"build": "pnpm run typecheck && pnpm -r --if-present run build",
|
"build": "pnpm run typecheck && pnpm -r --if-present run build",
|
||||||
"typecheck:libs": "tsc --build",
|
"typecheck:libs": "tsc --build",
|
||||||
"typecheck": "pnpm run typecheck:libs && pnpm -r --filter \"./artifacts/**\" --filter \"./scripts\" --if-present run typecheck",
|
"typecheck": "pnpm run typecheck:libs && pnpm -r --filter \"./artifacts/**\" --filter \"!./artifacts/mockup-sandbox\" --filter \"./scripts\" --if-present run typecheck",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"test": "bash scripts/test-local.sh",
|
"test": "bash scripts/test-local.sh",
|
||||||
"test:prod": "BASE=https://timmy.replit.app bash timmy_test.sh"
|
"test:prod": "BASE=https://timmy.replit.app bash timmy_test.sh"
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
GITEA_USER="${GITEA_USER:-replit}"
|
GITEA_USER="${GITEA_USER:-admin}"
|
||||||
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
||||||
|
|
||||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
||||||
@@ -35,8 +35,8 @@ if [[ -z "$GITEA_BASE" && -f "$REPO_ROOT/.env.local" ]]; then
|
|||||||
GITEA_BASE="$(grep '^GITEA_URL=' "$REPO_ROOT/.env.local" | cut -d= -f2- | tr -d '[:space:]')"
|
GITEA_BASE="$(grep '^GITEA_URL=' "$REPO_ROOT/.env.local" | cut -d= -f2- | tr -d '[:space:]')"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Fallback: Tailscale Funnel (permanent, no port changes)
|
# Fallback: Hermes VPS Gitea (public, no bore/Tailscale needed)
|
||||||
GITEA_BASE="${GITEA_BASE:-https://mm.tailb74b2d.ts.net}"
|
GITEA_BASE="${GITEA_BASE:-http://143.198.27.163:3000}"
|
||||||
|
|
||||||
# Strip trailing slash
|
# Strip trailing slash
|
||||||
GITEA_BASE="${GITEA_BASE%/}"
|
GITEA_BASE="${GITEA_BASE%/}"
|
||||||
@@ -68,9 +68,11 @@ info "Checking Gitea at ${GITEA_BASE} …"
|
|||||||
if ! curl -sf --max-time 8 "${GITEA_BASE}/api/v1/version" -o /dev/null 2>/dev/null; then
|
if ! curl -sf --max-time 8 "${GITEA_BASE}/api/v1/version" -o /dev/null 2>/dev/null; then
|
||||||
die "Gitea is not reachable at ${GITEA_BASE}.
|
die "Gitea is not reachable at ${GITEA_BASE}.
|
||||||
|
|
||||||
Check that your Tailscale Funnel is running:
|
Hermes VPS Gitea should always be accessible at:
|
||||||
tailscale funnel status
|
http://143.198.27.163:3000
|
||||||
tailscale funnel 3000 # to start it"
|
|
||||||
|
Check that the VPS is up:
|
||||||
|
ssh root@143.198.27.163 'systemctl status gitea'"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ok "Gitea reachable at ${GITEA_BASE}"
|
ok "Gitea reachable at ${GITEA_BASE}"
|
||||||
@@ -95,7 +97,10 @@ info "Branch: ${BRANCH}"
|
|||||||
|
|
||||||
# ─── 5. Update (or add) the gitea remote ─────────────────────────────────────
|
# ─── 5. Update (or add) the gitea remote ─────────────────────────────────────
|
||||||
|
|
||||||
REMOTE_URL_WITH_CREDS="${GITEA_BASE/https:\/\//https://${GITEA_USER}:${GITEA_TOKEN}@}/${GITEA_USER}/${REPO_NAME}.git"
|
# Inject credentials into URL regardless of http/https scheme
|
||||||
|
SCHEME="${GITEA_BASE%%://*}"
|
||||||
|
HOST_PATH="${GITEA_BASE#*://}"
|
||||||
|
REMOTE_URL_WITH_CREDS="${SCHEME}://${GITEA_USER}:${GITEA_TOKEN}@${HOST_PATH}/${GITEA_USER}/${REPO_NAME}.git"
|
||||||
|
|
||||||
if git -C "$REPO_ROOT" remote get-url gitea &>/dev/null; then
|
if git -C "$REPO_ROOT" remote get-url gitea &>/dev/null; then
|
||||||
git -C "$REPO_ROOT" remote set-url gitea "$REMOTE_URL_WITH_CREDS"
|
git -C "$REPO_ROOT" remote set-url gitea "$REMOTE_URL_WITH_CREDS"
|
||||||
|
|||||||
Reference in New Issue
Block a user