Skip to content

Commit bd47e75

Browse files
committed
feat: init
0 parents  commit bd47e75

File tree

298 files changed

+21915
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

298 files changed

+21915
-0
lines changed

.editorconfig

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# editorconfig.org
2+
root = true
3+
4+
[*]
5+
indent_size = 2
6+
indent_style = space
7+
end_of_line = lf
8+
charset = utf-8
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true
11+
12+
[*.md]
13+
trim_trailing_whitespace = false

.env.example

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
NUXT_PUBLIC_PREVIEW_MODE=true
2+
NUXT_PUBLIC_SLUG_DEFAULT_LENGTH=5
3+
NUXT_SITE_TOKEN=SinkCool
4+
NUXT_REDIRECT_STATUS_CODE=308
5+
NUXT_HOME_URL="https://sink.cool"
6+
NUXT_CF_ACCOUNT_ID=123456
7+
NUXT_CF_API_TOKEN=CloudflareAPIToken
8+
NUXT_DATASET=sink_v0
9+
NUXT_AI_MODEL="@cf/meta/llama-3-8b-instruct"
10+
NUXT_AI_PROMPT="You are a URL shortening assistant......"

.gitignore

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Nuxt dev/build outputs
2+
.output
3+
.data
4+
.nuxt
5+
.nitro
6+
.cache
7+
dist
8+
9+
# Node dependencies
10+
node_modules
11+
12+
# Logs
13+
logs
14+
*.log
15+
16+
# Misc
17+
.DS_Store
18+
.fleet
19+
.idea
20+
21+
# Local env files
22+
.env
23+
.env.*
24+
!.env.example
25+
.wrangler
26+
site
27+
cache

.node-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v20

.npmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
shamefully-hoist=true

.vscode/extensions.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"recommendations": [
3+
"vue.volar"
4+
]
5+
}

.vscode/settings.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
// Enable ESlint flat config support
3+
"eslint.experimental.useFlatConfig": true
4+
}

LICENSE

+661
Large diffs are not rendered by default.

README.md

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# ⚡ Sink
2+
3+
**A Simple / Speedy / Secrue Link Shortener with Analytics, 100% run on Cloudflare.**
4+
5+
![Hero](./public/image.png)
6+
7+
----
8+
9+
## ✨ Features
10+
11+
- **URL Shortening:** Compress your URLs to their minimal length.
12+
- **Analytics:** Monitor link analytics and gather insightful statistics.
13+
- **Serverless:** Deploy without the need for traditional servers.
14+
- **Customizable Slug:** Support for personalized slugs.
15+
- **🪄 AI Slug:** Leverage AI to generate slugs.
16+
- **Link Expiration:** Set expiration dates for your links.
17+
18+
## 🪧 Demo
19+
20+
Experience the demo at [Sink.Cool](https://sink.cool/dashboard). Log in using the Site Token below:
21+
22+
```txt
23+
Site Token: SinkCool
24+
```
25+
26+
## 🧱 Technologies Used
27+
28+
- **Framework**: [Nuxt](https://nuxt.com/)
29+
- **Database**: [Cloudflare Workers KV](https://developers.cloudflare.com/kv/)
30+
- **Analytics Engine**: [Cloudflare Workers Analytics Engine](https://developers.cloudflare.com/analytics/)
31+
- **UI Components**: [Shadcn-vue](https://www.shadcn-vue.com/)
32+
- **Styling:** [Tailwind CSS](https://tailwindcss.com/)
33+
- **Deployment**: [Cloudflare](https://www.cloudflare.com/)
34+
35+
## 🚗 Roadmap [WIP]
36+
37+
We welcome your contributions and PRs.
38+
39+
- [ ] Browser Extension
40+
- [ ] Raycast Extension
41+
- [ ] Apple Shortcuts
42+
- [ ] Enhanced Link Management (with Cloudflare D1)
43+
- [ ] Analytics Enhancements (Support for merging filter conditions)
44+
- [ ] Dashboard Performance Optimization (Infinite loading)
45+
- [ ] Units Test
46+
- [ ] Support for Other Deployment Platforms
47+
48+
## 🏗️ Deployment
49+
50+
1. [Fork](https://github.com/ccbikai/Sink/fork) the repository to your GitHub account.
51+
2. Create a [Cloudflare Pages](https://developers.cloudflare.com/pages/) project.
52+
3. Select the `Sink` repository and the `Nuxt.js` preset.
53+
4. Configure environment variables.
54+
1. `NUXT_SITE_TOKEN` length must exceed **8**.
55+
2. `NUXT_CF_ACCOUNT_ID` [find your account ID](https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids/).
56+
3. `NUXT_CF_API_TOKEN` Create a [Cloudflare API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/). This token requires `Account.Account Analytics` permissions at the very least. [Reference.](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/#authentication).
57+
58+
5. Save and deploy.
59+
6. Cancel the deployment, navigate to `Settings` -> `Functions`.
60+
1. KV namespace bindings. Bind the variable name `KV` to a KV namespace.
61+
2. Workers AI Bindings. Bind the variable name `AI` to the Workers AI Catalog. _Optional_
62+
3. Analytics Engine bindings. Bind the variable name `ANALYTICS` to the `sink` dataset, and enable [Cloudflare Analytics Engine beta](https://developers.cloudflare.com/analytics/analytics-engine/get-started/) for your account.
63+
7. Redeploy.
64+
65+
## ⚒️ Configuration
66+
67+
[Configuration Docs](./docs/configuration.md)
68+
69+
## 💖 Credits
70+
71+
1. [**Cloudflare**](https://www.cloudflare.com/)
72+
2. [**NuxtHub**](https://hub.nuxt.com/)
73+
3. [**Astroship**](https://astroship.web3templates.com/)
74+
75+
## ☕ Sponsor
76+
77+
1. [Follow Me on X(Twitter)](https://x.com/ccbikai).
78+
2. [Become a sponsor to on GitHub](https://github.com/sponsors/ccbikai).

app.config.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export default defineAppConfig({
2+
title: 'Sink',
3+
description: 'A Simple / Speedy / Secrue Link Shortener with Analytics, 100% run on Cloudflare.',
4+
image: 'https://sink.cool/banner.png',
5+
previewTTL: 24 * 3600, // 24h
6+
slugRegex: /^[a-z0-9]+(?:-[a-z0-9]+)*$/i,
7+
reserveSlug: [
8+
'dashboard',
9+
],
10+
})

app.vue

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script setup>
2+
const { title, description, image } = useAppConfig()
3+
useSeoMeta({
4+
title,
5+
description,
6+
ogTitle: title,
7+
ogDescription: description,
8+
ogImage: image,
9+
twitterTitle: title,
10+
twitterDescription: description,
11+
twitterImage: image,
12+
twitterCard: 'summary_large_image',
13+
})
14+
15+
useHead({
16+
htmlAttrs: {
17+
lang: 'en',
18+
},
19+
link: [
20+
{
21+
rel: 'icon',
22+
type: 'image/png',
23+
href: '/sink.png',
24+
},
25+
],
26+
})
27+
</script>
28+
29+
<template>
30+
<NuxtLayout>
31+
<NuxtLoadingIndicator color="#000" />
32+
<NuxtPage />
33+
<Toaster />
34+
</NuxtLayout>
35+
</template>

assets/css/tailwind.css

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
@layer base {
6+
:root {
7+
--background: 0 0% 100%;
8+
--foreground: 240 10% 3.9%;
9+
10+
--muted: 240 4.8% 95.9%;
11+
--muted-foreground: 240 3.8% 46.1%;
12+
13+
--popover: 0 0% 100%;
14+
--popover-foreground: 240 10% 3.9%;
15+
16+
--card: 0 0% 100%;
17+
--card-foreground: 240 10% 3.9%;
18+
19+
--border: 240 5.9% 90%;
20+
--input: 240 5.9% 90%;
21+
22+
--primary: 240 5.9% 10%;
23+
--primary-foreground: 0 0% 98%;
24+
25+
--secondary: 240 4.8% 95.9%;
26+
--secondary-foreground: 240 5.9% 10%;
27+
28+
--accent: 240 4.8% 95.9%;
29+
--accent-foreground: 240 5.9% 10%;
30+
31+
--destructive: 0 84.2% 60.2%;
32+
--destructive-foreground: 0 0% 98%;
33+
34+
--ring: 240 10% 3.9%;
35+
36+
--radius: 0.5rem;
37+
38+
--vis-tooltip-background-color: none !important;
39+
--vis-tooltip-border-color: none !important;
40+
--vis-tooltip-text-color: none !important;
41+
--vis-tooltip-shadow-color: none !important;
42+
--vis-tooltip-backdrop-filter: none !important;
43+
--vis-tooltip-padding: none !important;
44+
45+
--vis-primary-color: 198 93% 60%;
46+
--vis-secondary-color: 158 64% 52%;
47+
/* --vis-secondary-color: 160 81% 40%; */
48+
/* --vis-secondary-color: var(--primary); */
49+
--vis-text-color: var(--muted-foreground);
50+
}
51+
52+
.dark {
53+
--background: 240 10% 3.9%;
54+
--foreground: 0 0% 98%;
55+
56+
--muted: 240 3.7% 15.9%;
57+
--muted-foreground: 240 5% 64.9%;
58+
59+
--popover: 240 10% 3.9%;
60+
--popover-foreground: 0 0% 98%;
61+
62+
--card: 240 10% 3.9%;
63+
--card-foreground: 0 0% 98%;
64+
65+
--border: 240 3.7% 15.9%;
66+
--input: 240 3.7% 15.9%;
67+
68+
--primary: 0 0% 98%;
69+
--primary-foreground: 240 5.9% 10%;
70+
71+
--secondary: 240 3.7% 15.9%;
72+
--secondary-foreground: 0 0% 98%;
73+
74+
--accent: 240 3.7% 15.9%;
75+
--accent-foreground: 0 0% 98%;
76+
77+
--destructive: 0 62.8% 30.6%;
78+
--destructive-foreground: 0 0% 98%;
79+
80+
--ring: 240 4.9% 83.9%;
81+
}
82+
}
83+
84+
@layer base {
85+
* {
86+
@apply border-border;
87+
}
88+
body {
89+
@apply bg-background text-foreground;
90+
}
91+
}

assets/images/404.svg

+1
Loading

assets/images/cloudflare.png

21.2 KB
Loading

assets/images/hero.svg

+1
Loading

assets/images/nuxtjs.png

16 KB
Loading

assets/location/world-topo.json

+1
Large diffs are not rendered by default.

components.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"$schema": "https://shadcn-vue.com/schema.json",
3+
"style": "default",
4+
"typescript": true,
5+
"tailwind": {
6+
"config": "tailwind.config.js",
7+
"css": "assets/css/tailwind.css",
8+
"baseColor": "zinc",
9+
"cssVariables": true
10+
},
11+
"framework": "nuxt",
12+
"aliases": {
13+
"components": "@/components",
14+
"utils": "@/utils"
15+
}
16+
}

components/dashboard/Breadcrumb.vue

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script setup>
2+
import { NuxtLink } from '#components'
3+
4+
defineProps({
5+
title: {
6+
type: String,
7+
required: true,
8+
},
9+
})
10+
</script>
11+
12+
<template>
13+
<Breadcrumb class="flex justify-between">
14+
<BreadcrumbList>
15+
<BreadcrumbItem>
16+
<BreadcrumbLink href="/">
17+
Sink
18+
</BreadcrumbLink>
19+
</BreadcrumbItem>
20+
<BreadcrumbSeparator />
21+
<BreadcrumbItem>
22+
<BreadcrumbLink
23+
:as="NuxtLink"
24+
to="/dashboard"
25+
>
26+
Dashboard
27+
</BreadcrumbLink>
28+
</BreadcrumbItem>
29+
<BreadcrumbSeparator />
30+
<BreadcrumbItem>
31+
<BreadcrumbPage>{{ title }}</BreadcrumbPage>
32+
</BreadcrumbItem>
33+
</BreadcrumbList>
34+
35+
<DashboardLogout />
36+
</Breadcrumb>
37+
</template>

0 commit comments

Comments
 (0)