fix: migrate Old Book → Old Books via Vercel API endpoint
- api/migrate-old-books.js: one-time migration endpoint with proper FBQ auth (token + admin login fallback); merges contents if both exist - fbq-backfill: diagnostic logging on listDir (401 confirms FBQ_TOKEN has no read permission in edge fn context) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -32,42 +32,46 @@ function mime(name: string) {
|
||||
return m[e] ?? 'application/octet-stream';
|
||||
}
|
||||
|
||||
async function listDir(path: string): Promise<{ name: string; type: string }[] | null> {
|
||||
async function listDir(path: string, log?: string[]): Promise<{ name: string }[] | null> {
|
||||
const r = await fetch(`${FBQ_URL}/api/resources?source=${SOURCE}&path=${encodeURIComponent(path)}`, { headers: fbqH });
|
||||
if (log) log.push(`listDir ${path} → ${r.status}`);
|
||||
if (!r.ok) return null;
|
||||
const data = await r.json().catch(() => null);
|
||||
return [...(data?.folders ?? []), ...(data?.files ?? [])];
|
||||
const entries = Array.isArray(data?.entries) ? data.entries
|
||||
: [...(data?.folders ?? []), ...(data?.files ?? [])];
|
||||
return entries;
|
||||
}
|
||||
|
||||
async function renameDir(fromPath: string, toPath: string) {
|
||||
await fetch(`${FBQ_URL}/api/resources?source=${SOURCE}`, {
|
||||
async function fbDelete(path: string): Promise<boolean> {
|
||||
const r = await fetch(`${FBQ_URL}/api/resources?source=${SOURCE}&path=${encodeURIComponent(path)}`, { method: 'DELETE', headers: fbqH });
|
||||
return r.ok;
|
||||
}
|
||||
|
||||
async function fbRename(fromPath: string, toPath: string): Promise<boolean> {
|
||||
const r = await fetch(`${FBQ_URL}/api/resources?source=${SOURCE}`, {
|
||||
method: 'PATCH',
|
||||
headers: { ...fbqH, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ action: 'rename', items: [{ fromSource: SOURCE, fromPath, toSource: SOURCE, toPath }], overwrite: false }),
|
||||
body: JSON.stringify({ action: 'rename', items: [{ fromSource: SOURCE, fromPath, toSource: SOURCE, toPath }], overwrite: true }),
|
||||
});
|
||||
return r.ok;
|
||||
}
|
||||
|
||||
async function deleteDir(path: string) {
|
||||
await fetch(`${FBQ_URL}/api/resources?source=${SOURCE}&path=${encodeURIComponent(path.endsWith('/') ? path : path + '/')}`, {
|
||||
method: 'DELETE', headers: fbqH,
|
||||
});
|
||||
}
|
||||
|
||||
async function migrateOldBook(base: string) {
|
||||
async function migrateOldBook(base: string, log: string[]): Promise<void> {
|
||||
const src = `${base}/Old Book`;
|
||||
const dst = `${base}/Old Books`;
|
||||
const srcItems = await listDir(src);
|
||||
if (srcItems === null) return; // Old Book doesn't exist
|
||||
const dstItems = await listDir(dst);
|
||||
if (dstItems === null) {
|
||||
// Old Books doesn't exist — simple rename
|
||||
await renameDir(src, dst);
|
||||
const srcItems = await listDir(src, log);
|
||||
if (srcItems === null) return;
|
||||
if (srcItems.length === 0) {
|
||||
// Empty — just delete it
|
||||
const ok = await fbDelete(src);
|
||||
log.push(`${ok ? 'migrated' : 'migrate-fail'} (delete empty): ${src}`);
|
||||
} else {
|
||||
// Both exist — move each item from Old Book into Old Books, then delete Old Book
|
||||
// Has contents — move each item then delete
|
||||
for (const item of srcItems) {
|
||||
await renameDir(`${src}/${item.name}`, `${dst}/${item.name}`);
|
||||
await fbRename(`${src}/${item.name}`, `${dst}/${item.name}`);
|
||||
}
|
||||
await deleteDir(src);
|
||||
const ok = await fbDelete(src);
|
||||
log.push(`${ok ? 'migrated' : 'migrate-fail'} (merge+delete): ${src} → ${dst}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +134,7 @@ Deno.serve(async () => {
|
||||
|
||||
const taskIsNew = await mkdir(base);
|
||||
await Promise.all([mkdir(`${base}/Request Info`), mkdir(`${base}/Old Books`)]);
|
||||
await migrateOldBook(base);
|
||||
if (log.filter(l => l.startsWith('listDir')).length < 3) await migrateOldBook(base, log);
|
||||
|
||||
if (taskIsNew) { newTasks.push({ task, base, co, pr }); created++; }
|
||||
else skipped++;
|
||||
|
||||
Reference in New Issue
Block a user