upd wiki on chachy
This commit is contained in:
parent
64b5a82498
commit
f28dc954e8
|
|
@ -40,7 +40,8 @@
|
|||
"Bash(paru -S --noconfirm visual-studio-code-bin)",
|
||||
"Bash(code --version)",
|
||||
"Bash(code --install-extension svelte.svelte-vscode --install-extension bradlc.vscode-tailwindcss --install-extension esbenp.prettier-vscode --install-extension dbaeumer.vscode-eslint)",
|
||||
"Bash(git config:*)"
|
||||
"Bash(git config:*)",
|
||||
"Bash(FILE=\"/home/d-chrka@internal.lan/Projekte/chrka/Ka-Note/ka-note/client/src/routes/wiki/[id]/+page.svelte\"\npython3 - \"$FILE\" <<'EOF'\nimport sys\npath = sys.argv[1]\nwith open\\(path, 'r'\\) as f:\n content = f.read\\(\\)\n\nold = '\\\\t\\\\t\\\\t\\\\t<input\\\\n\\\\t\\\\t\\\\t\\\\t\\\\tclass=\"flex-1 bg-transparent text-2xl font-bold text-white outline-none placeholder:text-muted\"'\nnew = '\\\\t\\\\t\\\\t\\\\t<input\\\\n\\\\t\\\\t\\\\t\\\\t\\\\tbind:this={titleInputEl}\\\\n\\\\t\\\\t\\\\t\\\\t\\\\tclass=\"flex-1 bg-transparent text-2xl font-bold text-white outline-none placeholder:text-muted\"'\n\nif old in content:\n content = content.replace\\(old, new, 1\\)\n with open\\(path, 'w'\\) as f:\n f.write\\(content\\)\n print\\(\"replaced\"\\)\nelse:\n print\\(\"NOT FOUND\"\\)\n # debug: show actual bytes around the area\n idx = content.find\\('<input'\\)\n print\\(repr\\(content[idx:idx+100]\\)\\)\nEOF)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
1.2.37
|
||||
1.2.47
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
import { page } from '$app/state';
|
||||
import { goto } from '$app/navigation';
|
||||
import { db } from '$lib/db/schema';
|
||||
import { upsertPage, softDeletePage, togglePageFavorite, getNotebooksForPage, getBacklinksForPage, assignPageToNotebook, removePageFromNotebook, getAllNotebooks } from '$lib/db/repositories';
|
||||
import { upsertPage, softDeletePage, togglePageFavorite, getNotebooksForPage, getBacklinksForPage, assignPageToNotebook, removePageFromNotebook, getAllNotebooks, createPage } from '$lib/db/repositories';
|
||||
import MarkdownEditor from '$lib/components/MarkdownEditor.svelte';
|
||||
import RenderedMarkdown from '$lib/components/RenderedMarkdown.svelte';
|
||||
import ConfirmDialog from '$lib/components/ConfirmDialog.svelte';
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
let autosaveTimer: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
let titleInput = $state('');
|
||||
let titleInputEl = $state<HTMLInputElement | undefined>();
|
||||
let editorRef: MarkdownEditor | undefined = $state();
|
||||
let notebooks = $state<Notebook[]>([]);
|
||||
let backlinks = $state<Page[]>([]);
|
||||
|
|
@ -37,9 +38,10 @@
|
|||
// Re-initialize whenever pageId changes (SvelteKit reuses component on param navigation)
|
||||
$effect(() => {
|
||||
const id = pageId; // track reactively
|
||||
const openInEdit = page.url.searchParams.get('edit') === '1';
|
||||
currentPage = undefined;
|
||||
titleInitialized = false;
|
||||
editing = false;
|
||||
editing = openInEdit;
|
||||
notebooks = [];
|
||||
backlinks = [];
|
||||
db.pages.get(id).then(p => {
|
||||
|
|
@ -58,6 +60,10 @@
|
|||
if (currentPage && !titleInitialized) {
|
||||
titleInput = currentPage.title;
|
||||
titleInitialized = true;
|
||||
if (editing) {
|
||||
// focus title on next tick so the input is rendered
|
||||
setTimeout(() => titleInputEl?.focus(), 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -88,6 +94,14 @@
|
|||
currentPage = { ...currentPage!, title };
|
||||
}
|
||||
|
||||
async function addPage() {
|
||||
const newPage = await createPage('Neue Seite', scope === 'private');
|
||||
for (const nb of notebooks) {
|
||||
await assignPageToNotebook(newPage.id, nb.id);
|
||||
}
|
||||
goto(`/wiki/${newPage.id}?edit=1`);
|
||||
}
|
||||
|
||||
async function handleDelete() {
|
||||
await softDeletePage(pageId);
|
||||
goto('/wiki');
|
||||
|
|
@ -118,6 +132,7 @@
|
|||
<div class="flex items-center gap-3">
|
||||
{#if editing}
|
||||
<input
|
||||
bind:this={titleInputEl}
|
||||
class="flex-1 bg-transparent text-2xl font-bold text-white outline-none placeholder:text-muted"
|
||||
bind:value={titleInput}
|
||||
onblur={saveTitle}
|
||||
|
|
@ -153,6 +168,13 @@
|
|||
>
|
||||
{editing ? '✓ Fertig' : '✎ Bearbeiten'}
|
||||
</button>
|
||||
{#if !editing}
|
||||
<button
|
||||
class="rounded px-3 py-1.5 text-sm font-medium bg-white/10 text-[#ccc] hover:bg-white/20 hover:text-white transition-colors"
|
||||
onclick={addPage}
|
||||
title="Neue Seite mit gleichem Scope und Notizbüchern anlegen"
|
||||
>+ Neue Seite</button>
|
||||
{/if}
|
||||
{#if editing}
|
||||
<span class="text-xs {savedState === 'saved' ? 'text-muted' : savedState === 'saving' ? 'text-muted animate-pulse' : 'text-warning'}">
|
||||
{savedState === 'saved' ? '✓ gespeichert' : savedState === 'saving' ? '…' : '● ungespeichert'}
|
||||
|
|
@ -204,7 +226,8 @@
|
|||
|
||||
<!-- Content: read or edit -->
|
||||
{#if editing}
|
||||
<div class="rounded border border-accent/40 bg-sidebar/50 p-3 min-h-[300px]">
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div class="rounded border border-accent/40 bg-sidebar/50 p-3 min-h-[300px]" ondblclick={(e) => { if (!(e.target as Element).closest('.cm-editor')) switchToRead(); }}>
|
||||
<MarkdownEditor
|
||||
bind:this={editorRef}
|
||||
content={currentPage.body}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ export default defineConfig({
|
|||
})
|
||||
],
|
||||
server: {
|
||||
host: '127.0.0.1',
|
||||
host: 'localhost',
|
||||
proxy: {
|
||||
'/api': 'http://127.0.0.1:9000'
|
||||
'/api': 'http://localhost:9000'
|
||||
},
|
||||
headers: {
|
||||
'Cache-Control': 'no-store'
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
<#
|
||||
.PARAMETER CheckOnly
|
||||
Download and verify the prod DB without building or deploying.
|
||||
.PARAMETER SkipDbBackup
|
||||
Skip the DB download/verification step (use when DB hasn't changed since last run).
|
||||
#>
|
||||
param([switch]$CheckOnly)
|
||||
param([switch]$CheckOnly, [switch]$SkipDbBackup)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
|
|
@ -34,60 +36,66 @@ if ($CheckOnly) {
|
|||
$checkLabel = if ($CheckOnly) { " [check-only]" } else { "" }
|
||||
Write-Host "=== Version: $VERSION$checkLabel ===" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "=== Backup DB from Prod ===" -ForegroundColor Cyan
|
||||
$KuduToken = az account get-access-token --resource "https://management.azure.com" --query accessToken -o tsv
|
||||
if ($LASTEXITCODE -ne 0) { throw "Failed to get Azure access token" }
|
||||
$KuduDbUrl = "https://${APP}.scm.azurewebsites.net/api/vfs/data/ka-note.db"
|
||||
$AppUrl = "https://$APP.azurewebsites.net"
|
||||
$BackupDir = Join-Path $PSScriptRoot "backups"
|
||||
$null = New-Item -ItemType Directory -Path $BackupDir -Force
|
||||
$BackupFile = Join-Path $BackupDir ("ka-note-pre-deploy-$VERSION.db")
|
||||
|
||||
# Flush WAL before download so the snapshot is consistent (WAL file not included in Kudu download).
|
||||
$AppUrl = "https://$APP.azurewebsites.net"
|
||||
if ($env:KA_NOTE_DEPLOY_API_KEY) {
|
||||
Write-Host " Flushing WAL checkpoint before download..." -ForegroundColor DarkGray
|
||||
try {
|
||||
$cpResult = Invoke-RestMethod -Uri "$AppUrl/api/admin/checkpoint" -Method POST `
|
||||
-Headers @{ Authorization = "Bearer $env:KA_NOTE_DEPLOY_API_KEY" } `
|
||||
-UseBasicParsing -TimeoutSec 30
|
||||
Write-Host " Checkpoint: $($cpResult.checkpointed)/$($cpResult.log) pages" -ForegroundColor DarkGray
|
||||
} catch {
|
||||
Write-Host " Checkpoint call failed (continuing anyway): $_" -ForegroundColor Yellow
|
||||
}
|
||||
if ($SkipDbBackup) {
|
||||
Write-Host "=== Skipping DB Backup (-SkipDbBackup) ===" -ForegroundColor Yellow
|
||||
$KuduToken = $null
|
||||
} else {
|
||||
Write-Host " KA_NOTE_DEPLOY_API_KEY not set, skipping WAL checkpoint" -ForegroundColor Yellow
|
||||
}
|
||||
Write-Host "=== Backup DB from Prod ===" -ForegroundColor Cyan
|
||||
$KuduToken = az account get-access-token --resource "https://management.azure.com" --query accessToken -o tsv
|
||||
if ($LASTEXITCODE -ne 0) { throw "Failed to get Azure access token" }
|
||||
|
||||
Write-Host " Downloading ka-note.db from prod..." -ForegroundColor DarkGray
|
||||
try {
|
||||
Invoke-WebRequest -Uri $KuduDbUrl `
|
||||
-Headers @{ Authorization = "Bearer $KuduToken" } `
|
||||
-OutFile $BackupFile -UseBasicParsing
|
||||
} catch {
|
||||
throw "Kudu DB download failed: $_"
|
||||
}
|
||||
# Flush WAL before download so the snapshot is consistent (WAL file not included in Kudu download).
|
||||
if ($env:KA_NOTE_DEPLOY_API_KEY) {
|
||||
Write-Host " Flushing WAL checkpoint before download..." -ForegroundColor DarkGray
|
||||
try {
|
||||
$cpResult = Invoke-RestMethod -Uri "$AppUrl/api/admin/checkpoint" -Method POST `
|
||||
-Headers @{ Authorization = "Bearer $env:KA_NOTE_DEPLOY_API_KEY" } `
|
||||
-UseBasicParsing -TimeoutSec 30
|
||||
Write-Host " Checkpoint: $($cpResult.checkpointed)/$($cpResult.log) pages" -ForegroundColor DarkGray
|
||||
} catch {
|
||||
Write-Host " Checkpoint call failed (continuing anyway): $_" -ForegroundColor Yellow
|
||||
}
|
||||
} else {
|
||||
Write-Host " KA_NOTE_DEPLOY_API_KEY not set, skipping WAL checkpoint" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
$DbSize = (Get-Item $BackupFile).Length
|
||||
Write-Host " Downloaded: $([math]::Round($DbSize/1KB,1)) KB" -ForegroundColor DarkGray
|
||||
Write-Host " Downloading ka-note.db from prod..." -ForegroundColor DarkGray
|
||||
try {
|
||||
Invoke-WebRequest -Uri $KuduDbUrl `
|
||||
-Headers @{ Authorization = "Bearer $KuduToken" } `
|
||||
-OutFile $BackupFile -UseBasicParsing
|
||||
} catch {
|
||||
throw "Kudu DB download failed: $_"
|
||||
}
|
||||
|
||||
if ($DbSize -lt 4096) {
|
||||
throw "DB backup is suspiciously small ($DbSize bytes) - aborting deploy"
|
||||
}
|
||||
$DbSize = (Get-Item $BackupFile).Length
|
||||
Write-Host " Downloaded: $([math]::Round($DbSize/1KB,1)) KB" -ForegroundColor DarkGray
|
||||
|
||||
# Verify with sqlite3 (must be in PATH)
|
||||
$IntegrityResult = & sqlite3 $BackupFile "PRAGMA integrity_check;" 2>&1
|
||||
if ($LASTEXITCODE -ne 0 -or $IntegrityResult -ne 'ok') {
|
||||
throw "DB integrity_check FAILED: $IntegrityResult - aborting deploy. Backup saved at $BackupFile"
|
||||
}
|
||||
if ($DbSize -lt 4096) {
|
||||
throw "DB backup is suspiciously small ($DbSize bytes) - aborting deploy"
|
||||
}
|
||||
|
||||
Write-Host " integrity_check: ok ($([math]::Round($DbSize/1KB,1)) KB)" -ForegroundColor Green
|
||||
# Verify with sqlite3 (must be in PATH)
|
||||
$IntegrityResult = & sqlite3 $BackupFile "PRAGMA integrity_check;" 2>&1
|
||||
if ($LASTEXITCODE -ne 0 -or $IntegrityResult -ne 'ok') {
|
||||
throw "DB integrity_check FAILED: $IntegrityResult - aborting deploy. Backup saved at $BackupFile"
|
||||
}
|
||||
|
||||
if ($CheckOnly) {
|
||||
Write-Host ""
|
||||
Write-Host "=== Check passed -- no deploy performed ===" -ForegroundColor Green
|
||||
Write-Host " Backup: $BackupFile" -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
exit 0
|
||||
Write-Host " integrity_check: ok ($([math]::Round($DbSize/1KB,1)) KB)" -ForegroundColor Green
|
||||
|
||||
if ($CheckOnly) {
|
||||
Write-Host ""
|
||||
Write-Host "=== Check passed -- no deploy performed ===" -ForegroundColor Green
|
||||
Write-Host " Backup: $BackupFile" -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
|
||||
# Bump version now that DB check passed
|
||||
|
|
@ -209,6 +217,10 @@ while ($keepValidating) {
|
|||
$keepValidating = $true
|
||||
} elseif ($answer -eq 'yes') {
|
||||
Write-Host " Uploading backup to prod..." -ForegroundColor Cyan
|
||||
if (-not $KuduToken) {
|
||||
$KuduToken = az account get-access-token --resource "https://management.azure.com" --query accessToken -o tsv
|
||||
if ($LASTEXITCODE -ne 0) { throw "Failed to get Azure access token for restore" }
|
||||
}
|
||||
Invoke-WebRequest -Uri $KuduDbUrl `
|
||||
-Method PUT `
|
||||
-Headers @{ Authorization = "Bearer $KuduToken" } `
|
||||
|
|
|
|||
|
|
@ -1,4 +1,46 @@
|
|||
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
||||
CREATE TABLE `__new_contexts` (
|
||||
`id` text NOT NULL,
|
||||
`user_id` text NOT NULL,
|
||||
`name` text NOT NULL,
|
||||
`type` text NOT NULL,
|
||||
`sort_order` integer DEFAULT 0 NOT NULL,
|
||||
`meta` text,
|
||||
`archived_at` text,
|
||||
`is_favorite` integer DEFAULT false NOT NULL,
|
||||
`updated_at` text NOT NULL,
|
||||
`deleted_at` text,
|
||||
`version` integer DEFAULT 1 NOT NULL,
|
||||
PRIMARY KEY(`id`, `user_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
INSERT INTO `__new_contexts`("id", "user_id", "name", "type", "sort_order", "meta", "archived_at", "is_favorite", "updated_at", "deleted_at", "version") SELECT "id", '', "name", "type", "sort_order", "meta", "archived_at", "is_favorite", "updated_at", "deleted_at", "version" FROM `contexts`;--> statement-breakpoint
|
||||
DROP TABLE `contexts`;--> statement-breakpoint
|
||||
ALTER TABLE `__new_contexts` RENAME TO `contexts`;--> statement-breakpoint
|
||||
CREATE INDEX `contexts_updated_at_idx` ON `contexts` (`updated_at`);--> statement-breakpoint
|
||||
CREATE INDEX `contexts_user_id_idx` ON `contexts` (`user_id`);--> statement-breakpoint
|
||||
CREATE TABLE `__new_topics` (
|
||||
`id` text NOT NULL,
|
||||
`user_id` text NOT NULL,
|
||||
`context_id` text NOT NULL,
|
||||
`title` text NOT NULL,
|
||||
`status` text DEFAULT 'active' NOT NULL,
|
||||
`snooze_until` text,
|
||||
`sort_order` integer DEFAULT 0 NOT NULL,
|
||||
`is_new` integer DEFAULT true NOT NULL,
|
||||
`updated_at` text NOT NULL,
|
||||
`deleted_at` text,
|
||||
`version` integer DEFAULT 1 NOT NULL,
|
||||
PRIMARY KEY(`id`, `user_id`),
|
||||
FOREIGN KEY (`context_id`,`user_id`) REFERENCES `contexts`(`id`,`user_id`) ON UPDATE no action ON DELETE no action
|
||||
);
|
||||
--> statement-breakpoint
|
||||
INSERT INTO `__new_topics`("id", "user_id", "context_id", "title", "status", "snooze_until", "sort_order", "is_new", "updated_at", "deleted_at", "version") SELECT "id", '', "context_id", "title", "status", "snooze_until", "sort_order", "is_new", "updated_at", "deleted_at", "version" FROM `topics`;--> statement-breakpoint
|
||||
DROP TABLE `topics`;--> statement-breakpoint
|
||||
ALTER TABLE `__new_topics` RENAME TO `topics`;--> statement-breakpoint
|
||||
CREATE INDEX `topics_updated_at_idx` ON `topics` (`updated_at`);--> statement-breakpoint
|
||||
CREATE INDEX `topics_context_id_idx` ON `topics` (`context_id`);--> statement-breakpoint
|
||||
CREATE INDEX `topics_user_id_idx` ON `topics` (`user_id`);--> statement-breakpoint
|
||||
CREATE TABLE `__new_history_entries` (
|
||||
`id` text NOT NULL,
|
||||
`user_id` text NOT NULL,
|
||||
|
|
@ -18,7 +60,6 @@ CREATE TABLE `__new_history_entries` (
|
|||
INSERT INTO `__new_history_entries`("id", "user_id", "topic_id", "date", "text", "sort_order", "linked_context_id", "done_at", "updated_at", "deleted_at", "version") SELECT "id", '', "topic_id", "date", "text", "sort_order", "linked_context_id", "done_at", "updated_at", "deleted_at", "version" FROM `history_entries`;--> statement-breakpoint
|
||||
DROP TABLE `history_entries`;--> statement-breakpoint
|
||||
ALTER TABLE `__new_history_entries` RENAME TO `history_entries`;--> statement-breakpoint
|
||||
PRAGMA foreign_keys=ON;--> statement-breakpoint
|
||||
CREATE INDEX `history_entries_updated_at_idx` ON `history_entries` (`updated_at`);--> statement-breakpoint
|
||||
CREATE INDEX `history_entries_topic_id_idx` ON `history_entries` (`topic_id`);--> statement-breakpoint
|
||||
CREATE INDEX `history_entries_user_id_idx` ON `history_entries` (`user_id`);--> statement-breakpoint
|
||||
|
|
@ -44,45 +85,4 @@ ALTER TABLE `__new_ratings` RENAME TO `ratings`;--> statement-breakpoint
|
|||
CREATE INDEX `ratings_updated_at_idx` ON `ratings` (`updated_at`);--> statement-breakpoint
|
||||
CREATE INDEX `ratings_topic_id_idx` ON `ratings` (`topic_id`);--> statement-breakpoint
|
||||
CREATE INDEX `ratings_user_id_idx` ON `ratings` (`user_id`);--> statement-breakpoint
|
||||
CREATE TABLE `__new_topics` (
|
||||
`id` text NOT NULL,
|
||||
`user_id` text NOT NULL,
|
||||
`context_id` text NOT NULL,
|
||||
`title` text NOT NULL,
|
||||
`status` text DEFAULT 'active' NOT NULL,
|
||||
`snooze_until` text,
|
||||
`sort_order` integer DEFAULT 0 NOT NULL,
|
||||
`is_new` integer DEFAULT true NOT NULL,
|
||||
`updated_at` text NOT NULL,
|
||||
`deleted_at` text,
|
||||
`version` integer DEFAULT 1 NOT NULL,
|
||||
PRIMARY KEY(`id`, `user_id`),
|
||||
FOREIGN KEY (`context_id`,`user_id`) REFERENCES `contexts`(`id`,`user_id`) ON UPDATE no action ON DELETE no action
|
||||
);
|
||||
--> statement-breakpoint
|
||||
INSERT INTO `__new_topics`("id", "user_id", "context_id", "title", "status", "snooze_until", "sort_order", "is_new", "updated_at", "deleted_at", "version") SELECT "id", '', "context_id", "title", "status", "snooze_until", "sort_order", "is_new", "updated_at", "deleted_at", "version" FROM `topics`;--> statement-breakpoint
|
||||
DROP TABLE `topics`;--> statement-breakpoint
|
||||
ALTER TABLE `__new_topics` RENAME TO `topics`;--> statement-breakpoint
|
||||
CREATE INDEX `topics_updated_at_idx` ON `topics` (`updated_at`);--> statement-breakpoint
|
||||
CREATE INDEX `topics_context_id_idx` ON `topics` (`context_id`);--> statement-breakpoint
|
||||
CREATE INDEX `topics_user_id_idx` ON `topics` (`user_id`);--> statement-breakpoint
|
||||
CREATE TABLE `__new_contexts` (
|
||||
`id` text NOT NULL,
|
||||
`user_id` text NOT NULL,
|
||||
`name` text NOT NULL,
|
||||
`type` text NOT NULL,
|
||||
`sort_order` integer DEFAULT 0 NOT NULL,
|
||||
`meta` text,
|
||||
`archived_at` text,
|
||||
`is_favorite` integer DEFAULT false NOT NULL,
|
||||
`updated_at` text NOT NULL,
|
||||
`deleted_at` text,
|
||||
`version` integer DEFAULT 1 NOT NULL,
|
||||
PRIMARY KEY(`id`, `user_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
INSERT INTO `__new_contexts`("id", "user_id", "name", "type", "sort_order", "meta", "archived_at", "is_favorite", "updated_at", "deleted_at", "version") SELECT "id", '', "name", "type", "sort_order", "meta", "archived_at", "is_favorite", "updated_at", "deleted_at", "version" FROM `contexts`;--> statement-breakpoint
|
||||
DROP TABLE `contexts`;--> statement-breakpoint
|
||||
ALTER TABLE `__new_contexts` RENAME TO `contexts`;--> statement-breakpoint
|
||||
CREATE INDEX `contexts_updated_at_idx` ON `contexts` (`updated_at`);--> statement-breakpoint
|
||||
CREATE INDEX `contexts_user_id_idx` ON `contexts` (`user_id`);
|
||||
PRAGMA foreign_keys=ON;
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -48,7 +48,7 @@ router.post('/', handle('api-keys/create', async (c) => {
|
|||
|
||||
router.delete('/:id', handle('api-keys/delete', async (c) => {
|
||||
const { userId } = c.get('auth');
|
||||
const id = c.req.param('id');
|
||||
const id = c.req.param('id')!;
|
||||
|
||||
const result = await db
|
||||
.update(apiKeys)
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ backup.get('/list', handle('backup/list', async (c) => {
|
|||
|
||||
// Download a stored backup file
|
||||
backup.get('/download/:filename', handle('backup/download', async (c) => {
|
||||
const filename = c.req.param('filename');
|
||||
const filename = c.req.param('filename')!;
|
||||
let filePath: string;
|
||||
try {
|
||||
filePath = backupFilePath(filename);
|
||||
|
|
@ -85,7 +85,7 @@ backup.get('/download/:filename', handle('backup/download', async (c) => {
|
|||
|
||||
// Delete a stored backup
|
||||
backup.delete('/:filename', handle('backup/delete', async (c) => {
|
||||
const filename = c.req.param('filename');
|
||||
const filename = c.req.param('filename')!;
|
||||
try {
|
||||
await deleteBackup(filename);
|
||||
} catch (e: unknown) {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ sync.get('/pull', handle('sync/pull', async (c) => {
|
|||
|
||||
sync.get('/blob/:id', handle('sync/blob', async (c) => {
|
||||
const { userId } = c.get('auth');
|
||||
const id = c.req.param('id');
|
||||
const id = c.req.param('id')!;
|
||||
const blob = await fetchBlob(id, userId);
|
||||
if (!blob) return c.json({ error: 'Not found' }, 404);
|
||||
return c.json(blob);
|
||||
|
|
|
|||
Loading…
Reference in New Issue