diff --git a/docs/other/selfhosting.md b/docs/other/selfhosting.md index 070aacc15..6b0e0f5d2 100644 --- a/docs/other/selfhosting.md +++ b/docs/other/selfhosting.md @@ -112,12 +112,70 @@ #### Step 6: Deploy See the [VitePress deployment guide](https://vitepress.dev/guide/deploy) for more info. +### API Deployment + +If you want to deploy the API component (feedback system), you'll need to set up Cloudflare Workers and KV storage. + +#### Prerequisites + +- A [Cloudflare account](https://dash.cloudflare.com/sign-up) +- [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/install-and-update/) installed globally + +#### Step 1: Configure Wrangler + +Update `wrangler.toml` with your Cloudflare account information: + +1. Get your account ID from the Cloudflare dashboard (found in the right sidebar) +2. Replace the `account_id` value in `wrangler.toml` with your account ID +3. If you're using a custom domain, keep `workers_dev = false` and update the `routes` section +4. If you're deploying to `*.workers.dev`, set `workers_dev = true` and remove the `routes` section + +#### Step 2: Create KV Namespace + +Create a KV namespace for data storage: + +```bash +npx wrangler kv:namespace create STORAGE +``` + +This command will return a namespace ID. Copy this ID and replace the `id` value in the `[[kv_namespaces]]` section of `wrangler.toml` (line 14). + +**Note:** If you want to deploy without running Wrangler locally (e.g., in CI/CD), you'll need to: +1. Create the KV namespace manually in the Cloudflare dashboard +2. Update both the `account_id` and `id` values in `wrangler.toml` in your fork + +#### Step 3: Build and Deploy + +Build and deploy the API: + +```bash +# Build the API +pnpm api:build + +# Deploy to Cloudflare Workers +pnpm api:deploy +``` + +The API will be deployed to your configured domain or `*.workers.dev` subdomain. + +#### Rate Limiting (Optional) + +The rate limiter binding requires setup through the Cloudflare dashboard. You can skip this for basic deployments or configure it later through the Workers dashboard under the "Rate limiting" section. + #### Environment Variables -There are a few variables you can change if you wish to disable them: +##### Build-time Variables (for Documentation) -- `FMHY_BUILD_NSFW` - NSFW sidebar entry (experimental) -- `FMHY_BUILD_API` - API component for feedback system. +These variables control what gets included when building the documentation site: + +- `FMHY_BUILD_NSFW` - Enable NSFW sidebar entry (experimental) +- `FMHY_BUILD_API` - Enable API component for feedback system + +##### Runtime Variables (for API Worker) + +These variables are used by the deployed Cloudflare Worker API: + +- `WEBHOOK_URL` - Discord webhook URL for posting feedback messages (required for API feedback functionality) #### Troubleshooting diff --git a/package.json b/package.json index 008e0ac53..2d53e6101 100644 --- a/package.json +++ b/package.json @@ -24,51 +24,51 @@ "@fmhy/components": "^0.0.3", "@headlessui/vue": "^1.7.23", "@resvg/resvg-js": "^2.6.2", - "@vueuse/core": "^13.0.0", - "consola": "^3.2.3", - "feed": "^4.2.2", - "itty-fetcher": "^0.9.4", + "@vueuse/core": "^14.0.0", + "consola": "^3.4.2", + "feed": "^5.1.0", + "itty-fetcher": "^1.0.10", "nitro-cors": "^0.7.1", - "nitropack": "^2.11.6", + "nitropack": "^2.12.9", "nprogress": "^0.2.0", - "pathe": "^2.0.1", - "reka-ui": "^2.3.1", - "unocss": "66.1.0-beta.3", - "vitepress": "^1.6.3", - "vue": "^3.5.13", - "x-satori": "^0.2.0", - "zod": "^3.24.2" + "pathe": "^2.0.3", + "reka-ui": "^2.6.0", + "unocss": "66.5.5", + "vitepress": "^1.6.4", + "vue": "^3.5.24", + "x-satori": "^0.4.0", + "zod": "^4.1.12" }, "devDependencies": { - "@cloudflare/workers-types": "^4.20241230.0", - "@ianvs/prettier-plugin-sort-imports": "^4.3.1", - "@iconify-json/carbon": "^1.2.5", - "@iconify-json/fluent": "^1.2.23", + "@cloudflare/workers-types": "^4.20251107.0", + "@ianvs/prettier-plugin-sort-imports": "^4.7.0", + "@iconify-json/carbon": "^1.2.14", + "@iconify-json/fluent": "^1.2.34", "@iconify-json/fluent-mdl2": "^1.2.1", - "@iconify-json/gravity-ui": "^1.2.5", - "@iconify-json/heroicons-solid": "^1.2.0", - "@iconify-json/logos": "^1.2.4", - "@iconify-json/lucide": "^1.2.10", - "@iconify-json/material-symbols": "^1.2.22", - "@iconify-json/mdi": "^1.2.1", + "@iconify-json/gravity-ui": "^1.2.10", + "@iconify-json/heroicons-solid": "^1.2.1", + "@iconify-json/logos": "^1.2.10", + "@iconify-json/lucide": "^1.2.72", + "@iconify-json/material-symbols": "^1.2.44", + "@iconify-json/mdi": "^1.2.3", "@iconify-json/ph": "^1.2.2", - "@iconify-json/qlementine-icons": "^1.2.6", - "@iconify-json/simple-icons": "^1.2.12", - "@iconify-json/twemoji": "^1.2.1", - "@iconify/utils": "^2.3.0", - "@types/node": "^20.16.12", + "@iconify-json/qlementine-icons": "^1.2.11", + "@iconify-json/simple-icons": "^1.2.57", + "@iconify-json/twemoji": "^1.2.4", + "@iconify/utils": "^3.0.2", + "@types/node": "^24.10.0", "@types/nprogress": "^0.2.3", "nitro-cloudflare-dev": "^0.2.2", - "prettier": "^3.5.3", + "prettier": "^3.6.2", "prettier-plugin-pkgsort": "^0.2.1", - "prettier-plugin-tailwindcss": "^0.6.11", - "sass": "^1.85.1", - "typescript": "^5.8.2", - "unplugin-auto-import": "^0.18.3", + "prettier-plugin-tailwindcss": "^0.7.1", + "sass": "^1.93.3", + "typescript": "^5.9.3", + "unplugin-auto-import": "^20.2.0", "vite-plugin-optimize-exclude": "^0.0.1", - "vite-plugin-pwa": "^1.0.3", - "vite-plugin-terminal": "^1.2.0", - "wrangler": "^3.114.1" + "vite-plugin-pwa": "^1.1.0", + "vite-plugin-terminal": "^1.3.0", + "wrangler": "^4.46.0" }, "pnpm": { "peerDependencyRules": { diff --git a/pests-repellent/package.json b/pests-repellent/package.json index 4237c462f..9d0a3a88e 100644 --- a/pests-repellent/package.json +++ b/pests-repellent/package.json @@ -10,9 +10,9 @@ "cf-typegen": "wrangler types" }, "devDependencies": { - "@cloudflare/vitest-pool-workers": "^0.8.19", - "typescript": "^5.5.2", + "@cloudflare/vitest-pool-workers": "^0.10.5", + "typescript": "^5.9.3", "vitest": "~3.2.0", - "wrangler": "^4.20.5" + "wrangler": "^4.46.0" } } diff --git a/pests-repellent/pnpm-lock.yaml b/pests-repellent/pnpm-lock.yaml new file mode 100644 index 000000000..98c09c5c1 Binary files /dev/null and b/pests-repellent/pnpm-lock.yaml differ diff --git a/pests-repellent/test/index.spec.ts b/pests-repellent/test/index.spec.ts index 519729651..666a18cbf 100644 --- a/pests-repellent/test/index.spec.ts +++ b/pests-repellent/test/index.spec.ts @@ -14,11 +14,17 @@ describe('Hello World worker', () => { const response = await worker.fetch(request, env, ctx); // Wait for all `Promise`s passed to `ctx.waitUntil()` to settle before running test assertions await waitOnExecutionContext(ctx); - expect(await response.text()).toMatchInlineSnapshot(`"Hello World!"`); + expect(await response.text()).toMatchInlineSnapshot(` + "
This domain is for use in documentation examples without needing permission. Avoid use in operations.
This domain is for use in documentation examples without needing permission. Avoid use in operations.