feat(api): call WolfStar bot API via $api (legacy-style)#303
feat(api): call WolfStar bot API via $api (legacy-style)#303RedStar071 wants to merge 16 commits into
Conversation
Backport the old same-origin /api/commands and /api/languages structure, proxying to the internal bot API and normalizing alias → aliases. Co-authored-by: RedStar <redstar071@proton.me>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #303 +/- ##
==========================================
- Coverage 71.53% 71.14% -0.39%
==========================================
Files 167 169 +2
Lines 3302 3393 +91
Branches 702 730 +28
==========================================
+ Hits 2362 2414 +52
- Misses 447 468 +21
- Partials 493 511 +18
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Route dashboard guild/commands/languages handlers through sapphire-plugin-api with SAPPHIRE_AUTH cookie auth, instead of calling Discord REST locally. Keep moderation logs, members list, users, and auth on the Nuxt server. Co-authored-by: RedStar <redstar071@proton.me>
Restore the $api plugin against NUXT_PUBLIC_API_BASE_URL, point dashboard composables at bot paths, and keep a single /api/bot/** BFF for client-side auth cookie injection. Revert guild handlers to local Discord implementations. Co-authored-by: RedStar <redstar071@proton.me>
Use window instead of time for defineWrappedResponseHandler rate limits and apply lint formatting on related $api call sites. Co-authored-by: RedStar <redstar071@proton.me>
Remove the /api/bot BFF and always point $api at NUXT_PUBLIC_API_BASE_URL with credentials:include, matching legacy apiFetch behavior. Keep optional SSR sapphire cookie injection from the better-auth Discord session. Co-authored-by: RedStar <redstar071@proton.me>
Relocate sapphire auth crypto and BotApiCommand types to #shared so the $api plugin can import them without a dynamic #server/utils/bot-api load. Co-authored-by: RedStar <redstar071@proton.me>
Use camelCase botApi file and symbol names (BotApi* types, normalizeBotApiCommands, getOptionalBotApiAuthHeaders) in shared. Co-authored-by: RedStar <redstar071@proton.me>
Drop the redundant NUXT_BOT_API_OAUTH_SECRET alias; sapphire cookie encryption uses the existing Discord OAuth client secret. Co-authored-by: RedStar <redstar071@proton.me>
Add npmx-style runtime payload cache so HTML SSR can reuse a serialized _payload.json response and skip a second full render. Auth routes are excluded; Netlify uses Blobs storage for the payload-cache mount. Co-authored-by: RedStar <redstar071@proton.me>
Drop the duplicate BotApiCommand type and command normalizers; type commands fetches with the existing FlattenedCommand shape. Co-authored-by: RedStar <redstar071@proton.me>
Include baseURL, query, and auth headers in SSR fetch-cache keys so authenticated $api responses cannot bleed across users or filters. Remove nested UButton/role=region markup from CommandSubCategory so prerendered /commands passes html-validator when live bot API data loads. Co-authored-by: RedStar <redstar071@proton.me>
This comment has been minimized.
This comment has been minimized.
`$api` plugin setup was destructuring `runtimeConfig.discord.clientSecret`, which is undefined in the browser and crashed plugin init, causing hydration mismatches and View Transition failures in Playwright. Co-authored-by: RedStar <redstar071@proton.me>
…ture-api-88be Co-authored-by: RedStar <redstar071@proton.me>
Move node:crypto sapphire auth helpers out of #shared into server/utils/botApi and load them via a dynamic import inside the $api plugin's server branch so the client bundle never resolves crypto. Co-authored-by: RedStar <redstar071@proton.me>
| export function shouldCacheFetch(url: string, options: FetchCacheKeyOptions = {}): boolean { | ||
| if (typeof url === "string" && url.startsWith("/") && !options.baseURL) { | ||
| return true; | ||
| } | ||
|
|
||
| try { | ||
| return isAllowedDomain(resolveFetchCacheUrl(url, options)); |
There was a problem hiding this comment.
Do not cache mutations
shouldCacheFetch allows every method for allowed bot hosts, and cachedFetch returns a stored response before calling $fetch. The changed submitChanges path now sends PATCH /guilds/:id/settings through $api, so repeating the same settings body within the TTL hits this cache and skips the bot API update entirely while the UI treats it as saved. Restrict caching to safe read methods before checking the domain.
Artifacts
Repro: standalone mutation cache harness source
- Contains supporting evidence from the run (text/typescript; charset=utf-8).
Repro: mutation cache harness execution log
- Keeps the command output available without making the summary code-heavy.
Ran code and verified through T-Rex
Prompt To Fix With AI
This is a comment left during a code review.
Path: shared/utils/fetch-cache-config.ts
Line: 157-163
Comment:
**Do not cache mutations**
`shouldCacheFetch` allows every method for allowed bot hosts, and `cachedFetch` returns a stored response before calling `$fetch`. The changed `submitChanges` path now sends `PATCH /guilds/:id/settings` through `$api`, so repeating the same settings body within the TTL hits this cache and skips the bot API update entirely while the UI treats it as saved. Restrict caching to safe read methods before checking the domain.
How can I resolve this? If you propose a fix, please make it concise.
Summary
Restores legacy-style bot API access:
$apicallsNUXT_PUBLIC_API_BASE_URL(https://api.wolfstar.rocks) directly withcredentials: "include", like the oldapiFetchon the legacy branch.Changes
app/plugins/api.ts— always usesapiBaseUrl(no/api/botclient prefix); reads privatediscord.clientSecretonly on the server; loads sapphire cookie helpers via dynamic server importserver/utils/botApi(not#shared) sonode:cryptostays out of the client bundle; types remain in#shared/types/botApiSAPPHIRE_AUTHcookie via$authorizationwhen a Discord session exists/commands,/guilds/:id,/audit-logs, …)/_payload.jsonfrom cache for public ISR/cache routescachedFetchkeys include resolved host (baseURL), query, and auth headers so authenticated guild responses cannot cross users/filtersCommandSubCategoryaccordion markup fixed (no nested buttons / unnamed regions) so prerendered/commandspasses html-validator when live API data loadsTest plan
pnpm lint:fixpnpm typecheckpnpm test:unitpnpm build(html-validator clean on/commands)Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Confidence Score: 4/5
This PR has one contained issue to fix before merging.
The main API migration is coherent, and prior auth-scoped cache issues appear addressed. The remaining issue is a real mutation-cache bug that can skip repeated settings saves.
shared/utils/fetch-cache-config.ts;server/plugins/fetch-cache.tsWhat T-Rex did
Prompt To Fix All With AI
Reviews (6): Last reviewed commit: "fix(api): keep botApi crypto helpers ser..." | Re-trigger Greptile