feat: add url shortner
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Short link client — talks to the BFF /share endpoints.
|
||||
*
|
||||
* Used by the text-selection toolbar (`buildShortHighlightUrl`) and the
|
||||
* `/share/[code]` page (`resolveShortLink`).
|
||||
*/
|
||||
|
||||
import { bff, bffPost } from "@/lib/bff";
|
||||
|
||||
// Module-scoped cache: a single user shouldn't generate a fresh code every
|
||||
// time they re-click Share on the same selection. Keyed by the relative path
|
||||
// (including ?hl=…), this returns the same promise for repeat calls.
|
||||
const createCache = new Map<string, Promise<string | null>>();
|
||||
|
||||
type CreateResponse = { code: string };
|
||||
type ResolveResponse = { url: string };
|
||||
|
||||
/**
|
||||
* Create a short code for a same-site relative path (`/books/bg/18/66?hl=…`).
|
||||
* Returns `null` on any failure — caller should fall back to the long URL.
|
||||
*/
|
||||
export function createShortLink(longPath: string): Promise<string | null> {
|
||||
const cached = createCache.get(longPath);
|
||||
if (cached) return cached;
|
||||
|
||||
const promise = bffPost<CreateResponse>("/share", { url: longPath })
|
||||
.then((r) => r.code)
|
||||
.catch(() => null);
|
||||
|
||||
createCache.set(longPath, promise);
|
||||
// If the request fails, evict so the next click can retry instead of
|
||||
// returning the cached null forever.
|
||||
promise.then((code) => {
|
||||
if (code === null) createCache.delete(longPath);
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a short code to its full long path. Returns `null` when the code is
|
||||
* not found, expired, disabled, or the BFF is unreachable.
|
||||
*/
|
||||
export async function resolveShortLink(code: string): Promise<string | null> {
|
||||
try {
|
||||
const r = await bff<ResolveResponse>(`/share/${encodeURIComponent(code)}`, {
|
||||
revalidate: 0,
|
||||
});
|
||||
return r?.url ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user