feat(api): add /private/config/builder endpoint#2051
Conversation
Serves Google "Desktop app" OAuth client config (clientId, clientSecret,
scopes) to the Capgo CLI's Android `build init` onboarding flow. Returns
{ enabled: false } when GOOGLE_OAUTH_CLIENT_ID or
GOOGLE_OAUTH_CLIENT_SECRET worker env vars are missing/empty so
self-hosted and on-prem deployments can leave the feature off without
an error path. Scopes default to androidpublisher and are tunable via
GOOGLE_OAUTH_SCOPES (comma-separated).
Mirrors the structure and unauthenticated CORS-enabled posture of the
existing /private/config endpoint.
|
Caution Review failedFailed to post review comments 📝 WalkthroughWalkthroughThis PR introduces a new Config Builder endpoint that reads Google OAuth credentials from environment variables and returns the configuration via a private API route. The implementation is added to Supabase backend functions and wired into both Supabase and Cloudflare Workers private API routes, along with comprehensive unit tests. ChangesConfig Builder Endpoint
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
💡 Codex Reviewcapgo/cloudflare_workers/api/index.ts Line 103 in 467a711 This change wires ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
supabase/functions/_backend/private/config_google_oauth.ts (1)
15-17: 💤 Low valueConsider using
createHono()for consistency with other endpoints.Other private endpoints use
createHono()fromutils/hono.tswhich adds standard middleware for logging and error handling. DirectHonoinstantiation may bypass these.♻️ Suggested change
-import { Hono } from 'hono/tiny' -import { useCors } from '../utils/hono.ts' +import { createHono, useCors } from '../utils/hono.ts' import { getEnv } from '../utils/utils.ts' +import { version } from '../utils/version.ts' const DEFAULT_SCOPES = ['https://www.googleapis.com/auth/androidpublisher'] // ... parseScopes unchanged ... -export const app = new Hono<MiddlewareKeyVariables>() +export const app = createHono('config_google_oauth', version)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@supabase/functions/_backend/private/config_google_oauth.ts` around lines 15 - 17, The code instantiates Hono directly with "new Hono<MiddlewareKeyVariables>()" which bypasses the project's standard middleware; replace that direct instantiation with a call to createHono() from utils/hono.ts (so the exported "app" uses createHono() instead of new Hono) and then re-apply the existing middleware (e.g., ensure useCors is still mounted via app.use('/' , useCors)); keep the exported symbol name "app" and ensure MiddlewareKeyVariables typing is preserved when adapting to createHono.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@supabase/functions/_backend/private/config_google_oauth.ts`:
- Around line 15-17: The code instantiates Hono directly with "new
Hono<MiddlewareKeyVariables>()" which bypasses the project's standard
middleware; replace that direct instantiation with a call to createHono() from
utils/hono.ts (so the exported "app" uses createHono() instead of new Hono) and
then re-apply the existing middleware (e.g., ensure useCors is still mounted via
app.use('/' , useCors)); keep the exported symbol name "app" and ensure
MiddlewareKeyVariables typing is preserved when adapting to createHono.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e1e4d874-cdde-4fac-bd4a-6540a2f8d6bb
📒 Files selected for processing (3)
cloudflare_workers/api/index.tssupabase/functions/_backend/private/config_google_oauth.tstests/config-google-oauth.unit.test.ts
…vate function The endpoint was only wired into the Cloudflare API router, so local dev and Supabase-only/self-hosted deployments would 404 on it even with env vars set. Adding the same import and route registration to supabase/functions/private/index.ts gives both deployment targets the same surface, mirroring how the existing /private/config is wired in both files.
…/builder Generalizes the route name so it can serve other build-onboarding config in the future without another rename. The response shape and GOOGLE_OAUTH_* env var names stay as-is — the values it serves today are still Google "Desktop app" OAuth credentials for the CLI's `build init` Android flow. File and import variable renamed in lockstep: config_google_oauth.ts -> config_builder.ts configGoogleOauth -> configBuilder Both router entry points updated: - cloudflare_workers/api/index.ts - supabase/functions/private/index.ts
|



Summary
GET /private/config/builder, an unauthenticated CORS-enabled endpoint that serves build-onboarding configuration to the Capgo CLI'sbuild initflow.clientId,clientSecret,scopes. The route name is intentionally generic (/config/builder) so future build-related config can ride along without another rename.{ enabled: true, clientId, clientSecret, scopes }whenGOOGLE_OAUTH_CLIENT_IDandGOOGLE_OAUTH_CLIENT_SECRETworker env vars are both set, and{ enabled: false }otherwise — so self-hosted/on-prem deployments can leave the feature off without an error path.https://www.googleapis.com/auth/androidpublisherand can be overridden via the optionalGOOGLE_OAUTH_SCOPESenv var (comma-separated, whitespace-trimmed, falls back to default if all entries are empty)./private/configendpoint.Implementation
supabase/functions/_backend/private/config_builder.ts(~30 lines, Hono app with a single GET handler).cloudflare_workers/api/index.ts→appPrivate.route('/config/builder', ...)supabase/functions/private/index.ts→appGlobal.route('/config/builder', ...)tests/config-builder.unit.test.ts(8 tests) cover: enabled happy path, disabled branches (neither / only-id / only-secret / whitespace-only), and scope parsing (single / multi-with-whitespace / all-empty fallback to default).Out of Scope
CLI/submodule will read this endpoint and drive the OAuth flow./private/config/.wrangler.jsoncchanges — secrets are configured viawrangler secret put GOOGLE_OAUTH_CLIENT_IDandwrangler secret put GOOGLE_OAUTH_CLIENT_SECRET.Test plan
bunx vitest run tests/config-builder.unit.test.tsand sees 8 passing tests.bunx eslint supabase/functions/_backend/private/config_builder.ts cloudflare_workers/api/index.ts supabase/functions/private/index.ts tests/config-builder.unit.test.tsand sees no errors.curl https://api.capgo.app/private/config/builderreturns{ "enabled": false }until secrets are set, then{ "enabled": true, ... }afterwrangler secret put GOOGLE_OAUTH_CLIENT_IDandwrangler secret put GOOGLE_OAUTH_CLIENT_SECRET.supabase functions serve privatelocally) returns the same shape.Notes
arktypetest-suite failures observed running the full unit-test suite are pre-existing onorigin/main(verified) and unrelated to this PR.Summary by CodeRabbit
New Features
/config/builderthat retrieves OAuth authentication configuration by reading client credentials and scopes from environment variables, returning configuration status and details when properly configuredTests