diff --git a/README.md b/README.md index cfe81a9..bcfec92 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,8 @@ We welcome your contributions and PRs. - [Raycast-Sink](https://github.com/foru17/raycast-sink) - [x] Apple Shortcuts - [Sink Shortcuts](https://s.search1api.com/sink001) +- [x] iOS App + - [Sink](https://apps.apple.com/app/id6745417598) - [ ] Enhanced Link Management (with Cloudflare D1) - [ ] Analytics Enhancements (Support for merging filter conditions) - [ ] Dashboard Performance Optimization (Infinite loading) @@ -99,7 +101,7 @@ We welcome your contributions and PRs. 5. Save and deploy the project. 6. Cancel the deployment, then navigate to **Settings** -> **Bindings** -> **Add**: - - **KV Namespace**: Bind the variable name `KV` to a [KV namespace](https://developers.cloudflare.com/kv/) (create a new one under **Storage & Databases** -> **KV**). + - **KV Namespace**: Bind the variable name `KV` to a [KV namespace](https://developers.cloudflare.com/kv/) (create a new one under **Storage & Databases** -> **KV**). - **Workers AI** (_Optional_): Bind the variable name `AI` to the Workers AI Catalog. - **Analytics Engine**: - In **Workers & Pages**, go to **Account details** on the right side, find `Analytics Engine`, and click `Set up` to enable the free version. diff --git a/components/dashboard/links/Link.vue b/components/dashboard/links/Link.vue index 4b36f53..ccec374 100644 --- a/components/dashboard/links/Link.vue +++ b/components/dashboard/links/Link.vue @@ -165,7 +165,7 @@ function copyLink() { - {{ shortDate(link.createdAt) }} + {{ shortDate(link.createdAt) }}

Created At: {{ longDate(link.createdAt) }}

@@ -178,7 +178,7 @@ function copyLink() { - {{ shortDate(link.expiration) }} + {{ shortDate(link.expiration) }}

Expires At: {{ longDate(link.expiration) }}

diff --git a/package.json b/package.json index 1e7d088..0387a28 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sink", "type": "module", - "version": "0.1.10", + "version": "0.1.11", "private": true, "packageManager": "pnpm@9.15.1", "engines": { 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' } +}) diff --git a/server/utils/access-log.ts b/server/utils/access-log.ts index d3b60cf..92d362a 100644 --- a/server/utils/access-log.ts +++ b/server/utils/access-log.ts @@ -60,7 +60,7 @@ function blobs2logs(blobs: string[]) { } export function useAccessLog(event: H3Event) { - const ip = getHeader(event, 'x-real-ip') || getRequestIP(event, { xForwardedFor: true }) + const ip = getHeader(event, 'cf-connecting-ip') || getHeader(event, 'x-real-ip') || getRequestIP(event, { xForwardedFor: true }) const { host: referer } = parseURL(getHeader(event, 'referer'))