├── .github
└── workflows
│ └── deploy-to-cf.yaml
├── .gitignore
├── .prettierignore
├── LICENSE
├── README.md
├── package.json
├── pnpm-lock.yaml
├── prettier.config.js
├── renovate.json
├── src
├── index.ts
└── util.ts
├── tsconfig.json
└── wrangler.toml
/.github/workflows/deploy-to-cf.yaml:
--------------------------------------------------------------------------------
1 | name: Deploy to Cloudflare Workers
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | branches:
7 | - main
8 |
9 | concurrency:
10 | group: ${{ github.workflow }}-${{ github.ref }}
11 | cancel-in-progress: true
12 |
13 | jobs:
14 | deploy:
15 | runs-on: ubuntu-latest
16 | name: Deploy
17 | steps:
18 | - name: Checkout 🧳
19 | uses: actions/checkout@v4
20 |
21 | - name: Setup PNPM ⚙️
22 | uses: AkashRajpurohit/.github/.github/actions/setup-pnpm@main
23 | with:
24 | node_version: 20
25 | pnpm_version: 9
26 |
27 | - name: Install dependencies ⏬
28 | run: pnpm install --no-frozen-lockfile
29 |
30 | # Deploy
31 | - name: Deploy 🚀
32 | run: pnpm run deploy
33 | env:
34 | CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
35 | CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 |
3 | logs
4 | _.log
5 | npm-debug.log_
6 | yarn-debug.log*
7 | yarn-error.log*
8 | lerna-debug.log*
9 | .pnpm-debug.log*
10 |
11 | # Diagnostic reports (https://nodejs.org/api/report.html)
12 |
13 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
14 |
15 | # Runtime data
16 |
17 | pids
18 | _.pid
19 | _.seed
20 | \*.pid.lock
21 |
22 | # Directory for instrumented libs generated by jscoverage/JSCover
23 |
24 | lib-cov
25 |
26 | # Coverage directory used by tools like istanbul
27 |
28 | coverage
29 | \*.lcov
30 |
31 | # nyc test coverage
32 |
33 | .nyc_output
34 |
35 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
36 |
37 | .grunt
38 |
39 | # Bower dependency directory (https://bower.io/)
40 |
41 | bower_components
42 |
43 | # node-waf configuration
44 |
45 | .lock-wscript
46 |
47 | # Compiled binary addons (https://nodejs.org/api/addons.html)
48 |
49 | build/Release
50 |
51 | # Dependency directories
52 |
53 | node_modules/
54 | jspm_packages/
55 |
56 | # Snowpack dependency directory (https://snowpack.dev/)
57 |
58 | web_modules/
59 |
60 | # TypeScript cache
61 |
62 | \*.tsbuildinfo
63 |
64 | # Optional npm cache directory
65 |
66 | .npm
67 |
68 | # Optional eslint cache
69 |
70 | .eslintcache
71 |
72 | # Optional stylelint cache
73 |
74 | .stylelintcache
75 |
76 | # Microbundle cache
77 |
78 | .rpt2_cache/
79 | .rts2_cache_cjs/
80 | .rts2_cache_es/
81 | .rts2_cache_umd/
82 |
83 | # Optional REPL history
84 |
85 | .node_repl_history
86 |
87 | # Output of 'npm pack'
88 |
89 | \*.tgz
90 |
91 | # Yarn Integrity file
92 |
93 | .yarn-integrity
94 |
95 | # dotenv environment variable files
96 |
97 | .env
98 | .env.development.local
99 | .env.test.local
100 | .env.production.local
101 | .env.local
102 |
103 | # parcel-bundler cache (https://parceljs.org/)
104 |
105 | .cache
106 | .parcel-cache
107 |
108 | # Next.js build output
109 |
110 | .next
111 | out
112 |
113 | # Nuxt.js build / generate output
114 |
115 | .nuxt
116 | dist
117 |
118 | # Gatsby files
119 |
120 | .cache/
121 |
122 | # Comment in the public line in if your project uses Gatsby and not Next.js
123 |
124 | # https://nextjs.org/blog/next-9-1#public-directory-support
125 |
126 | # public
127 |
128 | # vuepress build output
129 |
130 | .vuepress/dist
131 |
132 | # vuepress v2.x temp and cache directory
133 |
134 | .temp
135 | .cache
136 |
137 | # Docusaurus cache and generated files
138 |
139 | .docusaurus
140 |
141 | # Serverless directories
142 |
143 | .serverless/
144 |
145 | # FuseBox cache
146 |
147 | .fusebox/
148 |
149 | # DynamoDB Local files
150 |
151 | .dynamodb/
152 |
153 | # TernJS port file
154 |
155 | .tern-port
156 |
157 | # Stores VSCode versions used for testing VSCode extensions
158 |
159 | .vscode-test
160 |
161 | # yarn v2
162 |
163 | .yarn/cache
164 | .yarn/unplugged
165 | .yarn/build-state.yml
166 | .yarn/install-state.gz
167 | .pnp.\*
168 |
169 | # wrangler project
170 |
171 | .dev.vars
172 | .wrangler
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.json
3 | *.yml
4 | *.yaml
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Akash Rajpurohit
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Time To Go!
8 |
9 |
10 | Simplify and Supercharge Your Links!
11 |
12 |
13 | Bug report
14 | ·
15 | Feature request
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | Time to Go is a utility service built on top of Cloudflare Workers that allows you share Go URLs.
35 |
36 | > Read more about Go URLs by visiting this Go URL [https://go.akashrajpurohit.com/b/go-urls](https://go.akashrajpurohit.com/b/go-urls?via=github-desc)
37 |
38 | # Motivation 💪
39 |
40 | Have you ever wanted to share a long and complex URL with others, only to find it difficult to remember or share? Time to Go solves this problem by providing you with the ability to create short, personalized Go URLs that are easy to remember and share.
41 |
42 | Whether you're sharing a link on social media or including it in a presentation, Time to Go simplifies the process and makes it more convenient for you and your audience.
43 |
44 | # Self Hosting Guide 📖
45 |
46 | To self-host Time to Go, follow these steps:
47 |
48 | ## Prerequisites 🏃🏻
49 |
50 | - Account with [Cloudflare](https://dash.cloudflare.com/sign-up). Everything required for this is available on Free plan as well.
51 | - [Node.js](https://nodejs.org/) installed on your machine if you want to run it locally first.
52 | - [PNPM](https://pnpm.io/) - The package manager used.
53 |
54 | ## KV Setup 📦
55 |
56 | To store the URL data, Time to Go utilizes Cloudflare's Key-Value (KV) store. Follow these steps to set up KV:
57 |
58 | 1. Create a KV namespace in your Cloudflare account.
59 | 2. Note down the generated KV namespace ID.
60 |
61 | We will use the UI for KV to add/update go-urls. Simple add a key (the short code) and value as the actual URL and click on "Add Entry"
62 |
63 | Go ahead and take some time to add some GO URLs for yourself.
64 |
65 | ## Environment Variables 👀
66 |
67 | Before deploying Time to Go, make sure to set the following environment variables:
68 |
69 | ### For Github Actions ⛏
70 |
71 | _All of the tokens mentioned in this section are required._
72 |
73 | - `CF_API_TOKEN`: Your Cloudflare API token. Create the API tokens from [here](https://dash.cloudflare.com/profile/api-tokens)
74 | - `CF_ACCOUNT_ID`: The ID of the Cloudflare zone where you want to deploy Time to Go.
75 |
76 | ### For Cloudflare Worker 👷🏼♂️
77 |
78 | - `NOT_FOUND_REDIRECT_URL` - This would be the URL where you want to re-direct a user when there is no go-url configured for incoming request.
79 |
80 | If this is not set then the service will just return a 404 response.
81 | - `REFERRER_TEXT` - If set, this will get attached to the go-url as a `ref` key in the url.
82 |
83 | For example if `REFERRER_TEXT=my-ref` and the URL is `https://example.com` it will be redirected to `https://example.com?ref=my-ref`
84 |
85 | ## Deployment 🚀
86 |
87 | To deploy Time to Go, follow these steps:
88 |
89 | 1. [Fork this repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo) to your own GitHub account.
90 | 2. Add the environment variables for the forked repository from the [Github Actions](#for-github-actions-) section.
91 | 3. Clone the forked repository to your local machine.
92 | 4. Navigate to the repository directory.
93 | 5. Install the dependencies by running the command: `pnpm install`.
94 | 6. Edit the `wrangler.toml` file and update the values for `kv_namespaces` with the KV id we created earlier for both `id` and `preview_id`.
95 | 7. Update the `vars` section to add the environment variables from the [Cloudflare worker](#for-cloudflare-worker-%EF%B8%8F) section.
96 | 8. Commit your changes and push them to your forked repository.
97 | 9. GitHub Actions will automatically trigger the deployment process. Wait for the action to complete.
98 |
99 | Congratulations! Time to Go is now deployed and ready to use.
100 |
101 | # Technology Stack 💻
102 |
103 | - Framework - [Hono](https://honojs.dev/)
104 | - Deployment - [Cloudflare Workers](https://workers.cloudflare.com/)
105 | - Storage - [Workers KV](https://www.cloudflare.com/products/workers-kv/)
106 |
107 | # Bugs or Requests 🐛
108 |
109 | If you encounter any problems feel free to open an [issue](https://github.com/AkashRajpurohit/time-to-go/issues/new?template=bug_report.md). If you feel the project is missing a feature, please raise a [ticket](https://github.com/AkashRajpurohit/time-to-go/issues/new?template=feature_request.md) on GitHub and I'll look into it. Pull requests are also welcome.
110 |
111 | # Where to find me? 👀
112 |
113 | [](https://akashrajpurohit.com/)
114 | [](https://twitter.com/AkashWhoCodes)
115 | [](https://linkedin.com/in/AkashRajpurohit)
116 | [](https://instagram.com/akashwho.codes/)
117 | [](https://t.me/AkashRajpurohit)
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "dev": "wrangler dev",
5 | "dev:remote": "wrangler dev --remote",
6 | "deploy": "wrangler deploy",
7 | "format": "prettier --write ."
8 | },
9 | "dependencies": {
10 | "hono": "^4.6.8"
11 | },
12 | "devDependencies": {
13 | "@cloudflare/workers-types": "^4.20241022.0",
14 | "prettier": "^3.3.3",
15 | "wrangler": "^3.84.1"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | dependencies:
11 | hono:
12 | specifier: ^4.6.8
13 | version: 4.6.8
14 | devDependencies:
15 | '@cloudflare/workers-types':
16 | specifier: ^4.20241022.0
17 | version: 4.20241022.0
18 | prettier:
19 | specifier: ^3.3.3
20 | version: 3.3.3
21 | wrangler:
22 | specifier: ^3.84.1
23 | version: 3.84.1(@cloudflare/workers-types@4.20241022.0)
24 |
25 | packages:
26 |
27 | '@cloudflare/kv-asset-handler@0.3.4':
28 | resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==}
29 | engines: {node: '>=16.13'}
30 |
31 | '@cloudflare/workerd-darwin-64@1.20241022.0':
32 | resolution: {integrity: sha512-1NNYun37myMTgCUiPQEJ0cMal4mKZVTpkD0b2tx9hV70xji+frVJcSK8YVLeUm1P+Rw1d/ct8DMgQuCpsz3Fsw==}
33 | engines: {node: '>=16'}
34 | cpu: [x64]
35 | os: [darwin]
36 |
37 | '@cloudflare/workerd-darwin-arm64@1.20241022.0':
38 | resolution: {integrity: sha512-FOO/0P0U82EsTLTdweNVgw+4VOk5nghExLPLSppdOziq6IR5HVgP44Kmq5LdsUeHUhwUmfOh9hzaTpkNzUqKvw==}
39 | engines: {node: '>=16'}
40 | cpu: [arm64]
41 | os: [darwin]
42 |
43 | '@cloudflare/workerd-linux-64@1.20241022.0':
44 | resolution: {integrity: sha512-RsNc19BQJG9yd+ngnjuDeG9ywZG+7t1L4JeglgceyY5ViMNMKVO7Zpbsu69kXslU9h6xyQG+lrmclg3cBpnhYA==}
45 | engines: {node: '>=16'}
46 | cpu: [x64]
47 | os: [linux]
48 |
49 | '@cloudflare/workerd-linux-arm64@1.20241022.0':
50 | resolution: {integrity: sha512-x5mUXpKxfsosxcFmcq5DaqLs37PejHYVRsNz1cWI59ma7aC4y4Qn6Tf3i0r9MwQTF/MccP4SjVslMU6m4W7IaA==}
51 | engines: {node: '>=16'}
52 | cpu: [arm64]
53 | os: [linux]
54 |
55 | '@cloudflare/workerd-windows-64@1.20241022.0':
56 | resolution: {integrity: sha512-eBCClx4szCOgKqOlxxbdNszMqQf3MRG1B9BRIqEM/diDfdR9IrZ8l3FaEm+l9gXgPmS6m1NBn40aWuGBl8UTSw==}
57 | engines: {node: '>=16'}
58 | cpu: [x64]
59 | os: [win32]
60 |
61 | '@cloudflare/workers-shared@0.7.0':
62 | resolution: {integrity: sha512-LLQRTqx7lKC7o2eCYMpyc5FXV8d0pUX6r3A+agzhqS9aoR5A6zCPefwQGcvbKx83ozX22ATZcemwxQXn12UofQ==}
63 | engines: {node: '>=16.7.0'}
64 |
65 | '@cloudflare/workers-types@4.20241022.0':
66 | resolution: {integrity: sha512-1zOAw5QIDKItzGatzCrEpfLOB1AuMTwVqKmbw9B9eBfCUGRFNfJYMrJxIwcse9EmKahsQt2GruqU00pY/GyXgg==}
67 |
68 | '@cspotcode/source-map-support@0.8.1':
69 | resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
70 | engines: {node: '>=12'}
71 |
72 | '@esbuild-plugins/node-globals-polyfill@0.2.3':
73 | resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==}
74 | peerDependencies:
75 | esbuild: '*'
76 |
77 | '@esbuild-plugins/node-modules-polyfill@0.2.2':
78 | resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==}
79 | peerDependencies:
80 | esbuild: '*'
81 |
82 | '@esbuild/android-arm64@0.17.19':
83 | resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==}
84 | engines: {node: '>=12'}
85 | cpu: [arm64]
86 | os: [android]
87 |
88 | '@esbuild/android-arm@0.17.19':
89 | resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==}
90 | engines: {node: '>=12'}
91 | cpu: [arm]
92 | os: [android]
93 |
94 | '@esbuild/android-x64@0.17.19':
95 | resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==}
96 | engines: {node: '>=12'}
97 | cpu: [x64]
98 | os: [android]
99 |
100 | '@esbuild/darwin-arm64@0.17.19':
101 | resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==}
102 | engines: {node: '>=12'}
103 | cpu: [arm64]
104 | os: [darwin]
105 |
106 | '@esbuild/darwin-x64@0.17.19':
107 | resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==}
108 | engines: {node: '>=12'}
109 | cpu: [x64]
110 | os: [darwin]
111 |
112 | '@esbuild/freebsd-arm64@0.17.19':
113 | resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==}
114 | engines: {node: '>=12'}
115 | cpu: [arm64]
116 | os: [freebsd]
117 |
118 | '@esbuild/freebsd-x64@0.17.19':
119 | resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==}
120 | engines: {node: '>=12'}
121 | cpu: [x64]
122 | os: [freebsd]
123 |
124 | '@esbuild/linux-arm64@0.17.19':
125 | resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==}
126 | engines: {node: '>=12'}
127 | cpu: [arm64]
128 | os: [linux]
129 |
130 | '@esbuild/linux-arm@0.17.19':
131 | resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==}
132 | engines: {node: '>=12'}
133 | cpu: [arm]
134 | os: [linux]
135 |
136 | '@esbuild/linux-ia32@0.17.19':
137 | resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==}
138 | engines: {node: '>=12'}
139 | cpu: [ia32]
140 | os: [linux]
141 |
142 | '@esbuild/linux-loong64@0.17.19':
143 | resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==}
144 | engines: {node: '>=12'}
145 | cpu: [loong64]
146 | os: [linux]
147 |
148 | '@esbuild/linux-mips64el@0.17.19':
149 | resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==}
150 | engines: {node: '>=12'}
151 | cpu: [mips64el]
152 | os: [linux]
153 |
154 | '@esbuild/linux-ppc64@0.17.19':
155 | resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==}
156 | engines: {node: '>=12'}
157 | cpu: [ppc64]
158 | os: [linux]
159 |
160 | '@esbuild/linux-riscv64@0.17.19':
161 | resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==}
162 | engines: {node: '>=12'}
163 | cpu: [riscv64]
164 | os: [linux]
165 |
166 | '@esbuild/linux-s390x@0.17.19':
167 | resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==}
168 | engines: {node: '>=12'}
169 | cpu: [s390x]
170 | os: [linux]
171 |
172 | '@esbuild/linux-x64@0.17.19':
173 | resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==}
174 | engines: {node: '>=12'}
175 | cpu: [x64]
176 | os: [linux]
177 |
178 | '@esbuild/netbsd-x64@0.17.19':
179 | resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==}
180 | engines: {node: '>=12'}
181 | cpu: [x64]
182 | os: [netbsd]
183 |
184 | '@esbuild/openbsd-x64@0.17.19':
185 | resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==}
186 | engines: {node: '>=12'}
187 | cpu: [x64]
188 | os: [openbsd]
189 |
190 | '@esbuild/sunos-x64@0.17.19':
191 | resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==}
192 | engines: {node: '>=12'}
193 | cpu: [x64]
194 | os: [sunos]
195 |
196 | '@esbuild/win32-arm64@0.17.19':
197 | resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==}
198 | engines: {node: '>=12'}
199 | cpu: [arm64]
200 | os: [win32]
201 |
202 | '@esbuild/win32-ia32@0.17.19':
203 | resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==}
204 | engines: {node: '>=12'}
205 | cpu: [ia32]
206 | os: [win32]
207 |
208 | '@esbuild/win32-x64@0.17.19':
209 | resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==}
210 | engines: {node: '>=12'}
211 | cpu: [x64]
212 | os: [win32]
213 |
214 | '@fastify/busboy@2.1.1':
215 | resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
216 | engines: {node: '>=14'}
217 |
218 | '@jridgewell/resolve-uri@3.1.2':
219 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
220 | engines: {node: '>=6.0.0'}
221 |
222 | '@jridgewell/sourcemap-codec@1.5.0':
223 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
224 |
225 | '@jridgewell/trace-mapping@0.3.9':
226 | resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
227 |
228 | '@types/node-forge@1.3.11':
229 | resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
230 |
231 | '@types/node@22.8.6':
232 | resolution: {integrity: sha512-tosuJYKrIqjQIlVCM4PEGxOmyg3FCPa/fViuJChnGeEIhjA46oy8FMVoF9su1/v8PNs2a8Q0iFNyOx0uOF91nw==}
233 |
234 | acorn-walk@8.3.4:
235 | resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==}
236 | engines: {node: '>=0.4.0'}
237 |
238 | acorn@8.14.0:
239 | resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
240 | engines: {node: '>=0.4.0'}
241 | hasBin: true
242 |
243 | anymatch@3.1.3:
244 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
245 | engines: {node: '>= 8'}
246 |
247 | as-table@1.0.55:
248 | resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==}
249 |
250 | binary-extensions@2.3.0:
251 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
252 | engines: {node: '>=8'}
253 |
254 | blake3-wasm@2.1.5:
255 | resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==}
256 |
257 | braces@3.0.3:
258 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
259 | engines: {node: '>=8'}
260 |
261 | capnp-ts@0.7.0:
262 | resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==}
263 |
264 | chokidar@3.6.0:
265 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
266 | engines: {node: '>= 8.10.0'}
267 |
268 | cookie@0.7.2:
269 | resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
270 | engines: {node: '>= 0.6'}
271 |
272 | data-uri-to-buffer@2.0.2:
273 | resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==}
274 |
275 | date-fns@4.1.0:
276 | resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
277 |
278 | debug@4.3.7:
279 | resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
280 | engines: {node: '>=6.0'}
281 | peerDependencies:
282 | supports-color: '*'
283 | peerDependenciesMeta:
284 | supports-color:
285 | optional: true
286 |
287 | defu@6.1.4:
288 | resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
289 |
290 | esbuild@0.17.19:
291 | resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==}
292 | engines: {node: '>=12'}
293 | hasBin: true
294 |
295 | escape-string-regexp@4.0.0:
296 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
297 | engines: {node: '>=10'}
298 |
299 | estree-walker@0.6.1:
300 | resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==}
301 |
302 | exit-hook@2.2.1:
303 | resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==}
304 | engines: {node: '>=6'}
305 |
306 | fill-range@7.1.1:
307 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
308 | engines: {node: '>=8'}
309 |
310 | fsevents@2.3.3:
311 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
312 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
313 | os: [darwin]
314 |
315 | function-bind@1.1.2:
316 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
317 |
318 | get-source@2.0.12:
319 | resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==}
320 |
321 | glob-parent@5.1.2:
322 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
323 | engines: {node: '>= 6'}
324 |
325 | glob-to-regexp@0.4.1:
326 | resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
327 |
328 | hasown@2.0.2:
329 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
330 | engines: {node: '>= 0.4'}
331 |
332 | hono@4.6.8:
333 | resolution: {integrity: sha512-f+2Ec9JAzabT61pglDiLJcF/DjiSefZkjCn9bzm1cYLGkD5ExJ3Jnv93ax9h0bn7UPLHF81KktoyjdQfWI2n1Q==}
334 | engines: {node: '>=16.9.0'}
335 |
336 | is-binary-path@2.1.0:
337 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
338 | engines: {node: '>=8'}
339 |
340 | is-core-module@2.15.1:
341 | resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==}
342 | engines: {node: '>= 0.4'}
343 |
344 | is-extglob@2.1.1:
345 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
346 | engines: {node: '>=0.10.0'}
347 |
348 | is-glob@4.0.3:
349 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
350 | engines: {node: '>=0.10.0'}
351 |
352 | is-number@7.0.0:
353 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
354 | engines: {node: '>=0.12.0'}
355 |
356 | itty-time@1.0.6:
357 | resolution: {integrity: sha512-+P8IZaLLBtFv8hCkIjcymZOp4UJ+xW6bSlQsXGqrkmJh7vSiMFSlNne0mCYagEE0N7HDNR5jJBRxwN0oYv61Rw==}
358 |
359 | magic-string@0.25.9:
360 | resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
361 |
362 | mime@3.0.0:
363 | resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==}
364 | engines: {node: '>=10.0.0'}
365 | hasBin: true
366 |
367 | miniflare@3.20241022.0:
368 | resolution: {integrity: sha512-x9Fbq1Hmz1f0osIT9Qmj78iX4UpCP2EqlZnA/tzj/3+I49vc3Kq0fNqSSKplcdf6HlCHdL3fOBicmreQF4BUUQ==}
369 | engines: {node: '>=16.13'}
370 | hasBin: true
371 |
372 | ms@2.1.3:
373 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
374 |
375 | mustache@4.2.0:
376 | resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==}
377 | hasBin: true
378 |
379 | nanoid@3.3.7:
380 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
381 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
382 | hasBin: true
383 |
384 | node-forge@1.3.1:
385 | resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
386 | engines: {node: '>= 6.13.0'}
387 |
388 | normalize-path@3.0.0:
389 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
390 | engines: {node: '>=0.10.0'}
391 |
392 | ohash@1.1.4:
393 | resolution: {integrity: sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==}
394 |
395 | path-parse@1.0.7:
396 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
397 |
398 | path-to-regexp@6.3.0:
399 | resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
400 |
401 | pathe@1.1.2:
402 | resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
403 |
404 | picomatch@2.3.1:
405 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
406 | engines: {node: '>=8.6'}
407 |
408 | prettier@3.3.3:
409 | resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==}
410 | engines: {node: '>=14'}
411 | hasBin: true
412 |
413 | printable-characters@1.0.42:
414 | resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==}
415 |
416 | readdirp@3.6.0:
417 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
418 | engines: {node: '>=8.10.0'}
419 |
420 | resolve.exports@2.0.2:
421 | resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==}
422 | engines: {node: '>=10'}
423 |
424 | resolve@1.22.8:
425 | resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
426 | hasBin: true
427 |
428 | rollup-plugin-inject@3.0.2:
429 | resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==}
430 | deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.
431 |
432 | rollup-plugin-node-polyfills@0.2.1:
433 | resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==}
434 |
435 | rollup-pluginutils@2.8.2:
436 | resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==}
437 |
438 | selfsigned@2.4.1:
439 | resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==}
440 | engines: {node: '>=10'}
441 |
442 | source-map@0.6.1:
443 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
444 | engines: {node: '>=0.10.0'}
445 |
446 | sourcemap-codec@1.4.8:
447 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
448 | deprecated: Please use @jridgewell/sourcemap-codec instead
449 |
450 | stacktracey@2.1.8:
451 | resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==}
452 |
453 | stoppable@1.1.0:
454 | resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==}
455 | engines: {node: '>=4', npm: '>=6'}
456 |
457 | supports-preserve-symlinks-flag@1.0.0:
458 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
459 | engines: {node: '>= 0.4'}
460 |
461 | to-regex-range@5.0.1:
462 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
463 | engines: {node: '>=8.0'}
464 |
465 | tslib@2.8.1:
466 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
467 |
468 | ufo@1.5.4:
469 | resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==}
470 |
471 | undici-types@6.19.8:
472 | resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
473 |
474 | undici@5.28.4:
475 | resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==}
476 | engines: {node: '>=14.0'}
477 |
478 | unenv-nightly@2.0.0-20241024-111401-d4156ac:
479 | resolution: {integrity: sha512-xJO1hfY+Te+/XnfCYrCbFbRcgu6XEODND1s5wnVbaBCkuQX7JXF7fHEXPrukFE2j8EOH848P8QN19VO47XN8hw==}
480 |
481 | workerd@1.20241022.0:
482 | resolution: {integrity: sha512-jyGXsgO9DRcJyx6Ovv7gUyDPc3UYC2i/E0p9GFUg6GUzpldw4Y93y9kOmdfsOnKZ3+lY53veSiUniiBPE6Q2NQ==}
483 | engines: {node: '>=16'}
484 | hasBin: true
485 |
486 | wrangler@3.84.1:
487 | resolution: {integrity: sha512-w27/QpIk2qz6aMIVi9T8cDcXMvh/RXjcL+vf4o5J2GpQAE4U7wTCNHyaY9H3oTJWRN97KqCAEbiHBNtTKoUJEw==}
488 | engines: {node: '>=16.17.0'}
489 | hasBin: true
490 | peerDependencies:
491 | '@cloudflare/workers-types': ^4.20241022.0
492 | peerDependenciesMeta:
493 | '@cloudflare/workers-types':
494 | optional: true
495 |
496 | ws@8.18.0:
497 | resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
498 | engines: {node: '>=10.0.0'}
499 | peerDependencies:
500 | bufferutil: ^4.0.1
501 | utf-8-validate: '>=5.0.2'
502 | peerDependenciesMeta:
503 | bufferutil:
504 | optional: true
505 | utf-8-validate:
506 | optional: true
507 |
508 | xxhash-wasm@1.0.2:
509 | resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==}
510 |
511 | youch@3.3.4:
512 | resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==}
513 |
514 | zod@3.23.8:
515 | resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
516 |
517 | snapshots:
518 |
519 | '@cloudflare/kv-asset-handler@0.3.4':
520 | dependencies:
521 | mime: 3.0.0
522 |
523 | '@cloudflare/workerd-darwin-64@1.20241022.0':
524 | optional: true
525 |
526 | '@cloudflare/workerd-darwin-arm64@1.20241022.0':
527 | optional: true
528 |
529 | '@cloudflare/workerd-linux-64@1.20241022.0':
530 | optional: true
531 |
532 | '@cloudflare/workerd-linux-arm64@1.20241022.0':
533 | optional: true
534 |
535 | '@cloudflare/workerd-windows-64@1.20241022.0':
536 | optional: true
537 |
538 | '@cloudflare/workers-shared@0.7.0':
539 | dependencies:
540 | mime: 3.0.0
541 | zod: 3.23.8
542 |
543 | '@cloudflare/workers-types@4.20241022.0': {}
544 |
545 | '@cspotcode/source-map-support@0.8.1':
546 | dependencies:
547 | '@jridgewell/trace-mapping': 0.3.9
548 |
549 | '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)':
550 | dependencies:
551 | esbuild: 0.17.19
552 |
553 | '@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19)':
554 | dependencies:
555 | esbuild: 0.17.19
556 | escape-string-regexp: 4.0.0
557 | rollup-plugin-node-polyfills: 0.2.1
558 |
559 | '@esbuild/android-arm64@0.17.19':
560 | optional: true
561 |
562 | '@esbuild/android-arm@0.17.19':
563 | optional: true
564 |
565 | '@esbuild/android-x64@0.17.19':
566 | optional: true
567 |
568 | '@esbuild/darwin-arm64@0.17.19':
569 | optional: true
570 |
571 | '@esbuild/darwin-x64@0.17.19':
572 | optional: true
573 |
574 | '@esbuild/freebsd-arm64@0.17.19':
575 | optional: true
576 |
577 | '@esbuild/freebsd-x64@0.17.19':
578 | optional: true
579 |
580 | '@esbuild/linux-arm64@0.17.19':
581 | optional: true
582 |
583 | '@esbuild/linux-arm@0.17.19':
584 | optional: true
585 |
586 | '@esbuild/linux-ia32@0.17.19':
587 | optional: true
588 |
589 | '@esbuild/linux-loong64@0.17.19':
590 | optional: true
591 |
592 | '@esbuild/linux-mips64el@0.17.19':
593 | optional: true
594 |
595 | '@esbuild/linux-ppc64@0.17.19':
596 | optional: true
597 |
598 | '@esbuild/linux-riscv64@0.17.19':
599 | optional: true
600 |
601 | '@esbuild/linux-s390x@0.17.19':
602 | optional: true
603 |
604 | '@esbuild/linux-x64@0.17.19':
605 | optional: true
606 |
607 | '@esbuild/netbsd-x64@0.17.19':
608 | optional: true
609 |
610 | '@esbuild/openbsd-x64@0.17.19':
611 | optional: true
612 |
613 | '@esbuild/sunos-x64@0.17.19':
614 | optional: true
615 |
616 | '@esbuild/win32-arm64@0.17.19':
617 | optional: true
618 |
619 | '@esbuild/win32-ia32@0.17.19':
620 | optional: true
621 |
622 | '@esbuild/win32-x64@0.17.19':
623 | optional: true
624 |
625 | '@fastify/busboy@2.1.1': {}
626 |
627 | '@jridgewell/resolve-uri@3.1.2': {}
628 |
629 | '@jridgewell/sourcemap-codec@1.5.0': {}
630 |
631 | '@jridgewell/trace-mapping@0.3.9':
632 | dependencies:
633 | '@jridgewell/resolve-uri': 3.1.2
634 | '@jridgewell/sourcemap-codec': 1.5.0
635 |
636 | '@types/node-forge@1.3.11':
637 | dependencies:
638 | '@types/node': 22.8.6
639 |
640 | '@types/node@22.8.6':
641 | dependencies:
642 | undici-types: 6.19.8
643 |
644 | acorn-walk@8.3.4:
645 | dependencies:
646 | acorn: 8.14.0
647 |
648 | acorn@8.14.0: {}
649 |
650 | anymatch@3.1.3:
651 | dependencies:
652 | normalize-path: 3.0.0
653 | picomatch: 2.3.1
654 |
655 | as-table@1.0.55:
656 | dependencies:
657 | printable-characters: 1.0.42
658 |
659 | binary-extensions@2.3.0: {}
660 |
661 | blake3-wasm@2.1.5: {}
662 |
663 | braces@3.0.3:
664 | dependencies:
665 | fill-range: 7.1.1
666 |
667 | capnp-ts@0.7.0:
668 | dependencies:
669 | debug: 4.3.7
670 | tslib: 2.8.1
671 | transitivePeerDependencies:
672 | - supports-color
673 |
674 | chokidar@3.6.0:
675 | dependencies:
676 | anymatch: 3.1.3
677 | braces: 3.0.3
678 | glob-parent: 5.1.2
679 | is-binary-path: 2.1.0
680 | is-glob: 4.0.3
681 | normalize-path: 3.0.0
682 | readdirp: 3.6.0
683 | optionalDependencies:
684 | fsevents: 2.3.3
685 |
686 | cookie@0.7.2: {}
687 |
688 | data-uri-to-buffer@2.0.2: {}
689 |
690 | date-fns@4.1.0: {}
691 |
692 | debug@4.3.7:
693 | dependencies:
694 | ms: 2.1.3
695 |
696 | defu@6.1.4: {}
697 |
698 | esbuild@0.17.19:
699 | optionalDependencies:
700 | '@esbuild/android-arm': 0.17.19
701 | '@esbuild/android-arm64': 0.17.19
702 | '@esbuild/android-x64': 0.17.19
703 | '@esbuild/darwin-arm64': 0.17.19
704 | '@esbuild/darwin-x64': 0.17.19
705 | '@esbuild/freebsd-arm64': 0.17.19
706 | '@esbuild/freebsd-x64': 0.17.19
707 | '@esbuild/linux-arm': 0.17.19
708 | '@esbuild/linux-arm64': 0.17.19
709 | '@esbuild/linux-ia32': 0.17.19
710 | '@esbuild/linux-loong64': 0.17.19
711 | '@esbuild/linux-mips64el': 0.17.19
712 | '@esbuild/linux-ppc64': 0.17.19
713 | '@esbuild/linux-riscv64': 0.17.19
714 | '@esbuild/linux-s390x': 0.17.19
715 | '@esbuild/linux-x64': 0.17.19
716 | '@esbuild/netbsd-x64': 0.17.19
717 | '@esbuild/openbsd-x64': 0.17.19
718 | '@esbuild/sunos-x64': 0.17.19
719 | '@esbuild/win32-arm64': 0.17.19
720 | '@esbuild/win32-ia32': 0.17.19
721 | '@esbuild/win32-x64': 0.17.19
722 |
723 | escape-string-regexp@4.0.0: {}
724 |
725 | estree-walker@0.6.1: {}
726 |
727 | exit-hook@2.2.1: {}
728 |
729 | fill-range@7.1.1:
730 | dependencies:
731 | to-regex-range: 5.0.1
732 |
733 | fsevents@2.3.3:
734 | optional: true
735 |
736 | function-bind@1.1.2: {}
737 |
738 | get-source@2.0.12:
739 | dependencies:
740 | data-uri-to-buffer: 2.0.2
741 | source-map: 0.6.1
742 |
743 | glob-parent@5.1.2:
744 | dependencies:
745 | is-glob: 4.0.3
746 |
747 | glob-to-regexp@0.4.1: {}
748 |
749 | hasown@2.0.2:
750 | dependencies:
751 | function-bind: 1.1.2
752 |
753 | hono@4.6.8: {}
754 |
755 | is-binary-path@2.1.0:
756 | dependencies:
757 | binary-extensions: 2.3.0
758 |
759 | is-core-module@2.15.1:
760 | dependencies:
761 | hasown: 2.0.2
762 |
763 | is-extglob@2.1.1: {}
764 |
765 | is-glob@4.0.3:
766 | dependencies:
767 | is-extglob: 2.1.1
768 |
769 | is-number@7.0.0: {}
770 |
771 | itty-time@1.0.6: {}
772 |
773 | magic-string@0.25.9:
774 | dependencies:
775 | sourcemap-codec: 1.4.8
776 |
777 | mime@3.0.0: {}
778 |
779 | miniflare@3.20241022.0:
780 | dependencies:
781 | '@cspotcode/source-map-support': 0.8.1
782 | acorn: 8.14.0
783 | acorn-walk: 8.3.4
784 | capnp-ts: 0.7.0
785 | exit-hook: 2.2.1
786 | glob-to-regexp: 0.4.1
787 | stoppable: 1.1.0
788 | undici: 5.28.4
789 | workerd: 1.20241022.0
790 | ws: 8.18.0
791 | youch: 3.3.4
792 | zod: 3.23.8
793 | transitivePeerDependencies:
794 | - bufferutil
795 | - supports-color
796 | - utf-8-validate
797 |
798 | ms@2.1.3: {}
799 |
800 | mustache@4.2.0: {}
801 |
802 | nanoid@3.3.7: {}
803 |
804 | node-forge@1.3.1: {}
805 |
806 | normalize-path@3.0.0: {}
807 |
808 | ohash@1.1.4: {}
809 |
810 | path-parse@1.0.7: {}
811 |
812 | path-to-regexp@6.3.0: {}
813 |
814 | pathe@1.1.2: {}
815 |
816 | picomatch@2.3.1: {}
817 |
818 | prettier@3.3.3: {}
819 |
820 | printable-characters@1.0.42: {}
821 |
822 | readdirp@3.6.0:
823 | dependencies:
824 | picomatch: 2.3.1
825 |
826 | resolve.exports@2.0.2: {}
827 |
828 | resolve@1.22.8:
829 | dependencies:
830 | is-core-module: 2.15.1
831 | path-parse: 1.0.7
832 | supports-preserve-symlinks-flag: 1.0.0
833 |
834 | rollup-plugin-inject@3.0.2:
835 | dependencies:
836 | estree-walker: 0.6.1
837 | magic-string: 0.25.9
838 | rollup-pluginutils: 2.8.2
839 |
840 | rollup-plugin-node-polyfills@0.2.1:
841 | dependencies:
842 | rollup-plugin-inject: 3.0.2
843 |
844 | rollup-pluginutils@2.8.2:
845 | dependencies:
846 | estree-walker: 0.6.1
847 |
848 | selfsigned@2.4.1:
849 | dependencies:
850 | '@types/node-forge': 1.3.11
851 | node-forge: 1.3.1
852 |
853 | source-map@0.6.1: {}
854 |
855 | sourcemap-codec@1.4.8: {}
856 |
857 | stacktracey@2.1.8:
858 | dependencies:
859 | as-table: 1.0.55
860 | get-source: 2.0.12
861 |
862 | stoppable@1.1.0: {}
863 |
864 | supports-preserve-symlinks-flag@1.0.0: {}
865 |
866 | to-regex-range@5.0.1:
867 | dependencies:
868 | is-number: 7.0.0
869 |
870 | tslib@2.8.1: {}
871 |
872 | ufo@1.5.4: {}
873 |
874 | undici-types@6.19.8: {}
875 |
876 | undici@5.28.4:
877 | dependencies:
878 | '@fastify/busboy': 2.1.1
879 |
880 | unenv-nightly@2.0.0-20241024-111401-d4156ac:
881 | dependencies:
882 | defu: 6.1.4
883 | ohash: 1.1.4
884 | pathe: 1.1.2
885 | ufo: 1.5.4
886 |
887 | workerd@1.20241022.0:
888 | optionalDependencies:
889 | '@cloudflare/workerd-darwin-64': 1.20241022.0
890 | '@cloudflare/workerd-darwin-arm64': 1.20241022.0
891 | '@cloudflare/workerd-linux-64': 1.20241022.0
892 | '@cloudflare/workerd-linux-arm64': 1.20241022.0
893 | '@cloudflare/workerd-windows-64': 1.20241022.0
894 |
895 | wrangler@3.84.1(@cloudflare/workers-types@4.20241022.0):
896 | dependencies:
897 | '@cloudflare/kv-asset-handler': 0.3.4
898 | '@cloudflare/workers-shared': 0.7.0
899 | '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19)
900 | '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19)
901 | blake3-wasm: 2.1.5
902 | chokidar: 3.6.0
903 | date-fns: 4.1.0
904 | esbuild: 0.17.19
905 | itty-time: 1.0.6
906 | miniflare: 3.20241022.0
907 | nanoid: 3.3.7
908 | path-to-regexp: 6.3.0
909 | resolve: 1.22.8
910 | resolve.exports: 2.0.2
911 | selfsigned: 2.4.1
912 | source-map: 0.6.1
913 | unenv: unenv-nightly@2.0.0-20241024-111401-d4156ac
914 | workerd: 1.20241022.0
915 | xxhash-wasm: 1.0.2
916 | optionalDependencies:
917 | '@cloudflare/workers-types': 4.20241022.0
918 | fsevents: 2.3.3
919 | transitivePeerDependencies:
920 | - bufferutil
921 | - supports-color
922 | - utf-8-validate
923 |
924 | ws@8.18.0: {}
925 |
926 | xxhash-wasm@1.0.2: {}
927 |
928 | youch@3.3.4:
929 | dependencies:
930 | cookie: 0.7.2
931 | mustache: 4.2.0
932 | stacktracey: 2.1.8
933 |
934 | zod@3.23.8: {}
935 |
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | singleQuote: true,
3 | semi: true,
4 | trailingComma: 'es5',
5 | };
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:base"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Hono } from 'hono';
2 | import { appendReferrerTextToUrl } from './util';
3 |
4 | type Bindings = {
5 | GO_URLS: KVNamespace;
6 | NOT_FOUND_REDIRECT_URL: string;
7 | REFERRER_TEXT: string;
8 | };
9 |
10 | const app = new Hono<{ Bindings: Bindings }>();
11 |
12 | app.get('/', (c) =>
13 | c.redirect('https://github.com/AkashRajpurohit/time-to-go', 307)
14 | );
15 |
16 | app.get('*', async (c) => {
17 | const incomingUrl = new URL(c.req.url);
18 | const existingSearchParams = incomingUrl.searchParams;
19 |
20 | // Get the URL pathname as input text minus the leading "/"
21 | const text = incomingUrl.pathname.slice(1);
22 | const { NOT_FOUND_REDIRECT_URL, REFERRER_TEXT } = c.env;
23 | const url = await c.env.GO_URLS.get(text);
24 |
25 | if (!url) {
26 | if (NOT_FOUND_REDIRECT_URL) {
27 | const redirectUrl = appendReferrerTextToUrl(
28 | NOT_FOUND_REDIRECT_URL,
29 | REFERRER_TEXT,
30 | existingSearchParams
31 | );
32 | return c.redirect(redirectUrl);
33 | }
34 |
35 | // NOT_FOUND_REDIRECT_URL is not configured so just return 404 response
36 | return c.text('Not found', 404);
37 | }
38 |
39 | const urlWithRef = appendReferrerTextToUrl(url, REFERRER_TEXT, existingSearchParams);
40 |
41 | return c.redirect(urlWithRef, 307);
42 | })
43 |
44 | export default app;
45 |
--------------------------------------------------------------------------------
/src/util.ts:
--------------------------------------------------------------------------------
1 | export const appendReferrerTextToUrl = (
2 | url = '/',
3 | referrerText: string,
4 | existingSearchParams: URLSearchParams
5 | ) => {
6 | if (!referrerText) return url;
7 |
8 | const uri = new URL(url);
9 | uri.searchParams.append('ref', referrerText);
10 |
11 | // Append all existing search params to the redirected URL as well
12 | // Note: if existing URL had a ref property then that will override
13 | // the referrerText we set above
14 | for (const [key, value] of existingSearchParams.entries()) {
15 | if (key === 'ref') {
16 | uri.searchParams.delete('ref');
17 | }
18 |
19 | uri.searchParams.append(key, value);
20 | }
21 |
22 | return uri.toString();
23 | };
24 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "module": "ESNext",
5 | "moduleResolution": "node",
6 | "esModuleInterop": true,
7 | "strict": true,
8 | "lib": [
9 | "esnext"
10 | ],
11 | "types": [
12 | "@cloudflare/workers-types"
13 | ],
14 | "jsx": "react-jsx",
15 | "jsxFragmentFactory": "Fragment",
16 | "jsxImportSource": "hono/jsx"
17 | }
18 | }
--------------------------------------------------------------------------------
/wrangler.toml:
--------------------------------------------------------------------------------
1 | name = "go-urls"
2 | main = "src/index.ts"
3 | compatibility_date = "2023-01-01"
4 |
5 | [[kv_namespaces]]
6 | binding = "GO_URLS"
7 | preview_id = "6ec3404005ee4537bcb35a7660c4f93c"
8 | id = "6ec3404005ee4537bcb35a7660c4f93c"
9 |
10 | [vars]
11 | NOT_FOUND_REDIRECT_URL = "https://akashrajpurohit.com/404/"
12 | REFERRER_TEXT = "go.akashrajpurohit.com"
13 |
14 | [observability]
15 | enabled = true
16 | head_sampling_rate = 1
17 |
--------------------------------------------------------------------------------