From c1ac0bf9f3104c7a8dbd2c8f240c76b22d778d9f Mon Sep 17 00:00:00 2001 From: "anirut.k" Date: Fri, 21 Mar 2025 13:45:41 +0700 Subject: [PATCH] feat: implement link upsert API endpoint - Adds a new API endpoint for creating and retrieving links - Validates link data using LinkSchema - Supports case sensitivity for link slugs - Handles existing links by returning the short link and status - Creates new links with expiration metadata in Cloudflare KV store --- server/api/link/upsert.post.ts | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 server/api/link/upsert.post.ts diff --git a/server/api/link/upsert.post.ts b/server/api/link/upsert.post.ts new file mode 100644 index 0000000..2b7da43 --- /dev/null +++ b/server/api/link/upsert.post.ts @@ -0,0 +1,38 @@ +import { LinkSchema } from '@/schemas/link' + +export default eventHandler(async (event) => { + const link = await readValidatedBody(event, LinkSchema.parse) + const { caseSensitive } = useRuntimeConfig(event) + + if (!caseSensitive) { + link.slug = link.slug.toLowerCase() + } + + const { cloudflare } = event.context + const { KV } = cloudflare.env + + // Check if link exists + const existingLink = await KV.get(`link:${link.slug}`, { type: 'json' }) + + if (existingLink) { + // If link exists, return it along with the short link + const shortLink = `${getRequestProtocol(event)}://${getRequestHost(event)}/${link.slug}` + return { link: existingLink, shortLink, status: 'existing' } + } + + // If link doesn't exist, create it + const expiration = getExpiration(event, link.expiration) + + await KV.put(`link:${link.slug}`, JSON.stringify(link), { + expiration, + metadata: { + expiration, + url: link.url, + comment: link.comment, + }, + }) + + setResponseStatus(event, 201) + const shortLink = `${getRequestProtocol(event)}://${getRequestHost(event)}/${link.slug}` + return { link, shortLink, status: 'created' } +})