-
Notifications
You must be signed in to change notification settings - Fork 953
Port our electric sql proxy to cloudflare #1867
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
bdd580e
bd517d5
70ba459
3c2b715
10444fa
9b4e62f
1acd1e9
31f711d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,45 +3,50 @@ import { auth } from "@superset/auth/server"; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { env } from "@/env"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { buildWhereClause } from "./utils"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interface AuthInfo { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| userId: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| organizationIds: string[]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async function authenticate(request: Request): Promise<AuthInfo | null> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const bearer = request.headers.get("Authorization"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (bearer?.startsWith("Bearer ")) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const token = bearer.slice(7); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { payload } = await auth.api.verifyJWT({ body: { token } }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (payload?.sub && Array.isArray(payload.organizationIds)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| userId: payload.sub, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| organizationIds: payload.organizationIds as string[], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+16
to
+21
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: find . -type f -name "route.ts" | grep -E "electric.*path" | head -5Repository: superset-sh/superset Length of output: 114 🏁 Script executed: git ls-files | grep -E "apps/api/src/app/api/electric.*route\.ts"Repository: superset-sh/superset Length of output: 112 🏁 Script executed: find . -path "*/apps/api/src/app/api/electric/*" -name "*.ts" -type fRepository: superset-sh/superset Length of output: 165 🏁 Script executed: cat -n ./apps/api/src/app/api/electric/[...path]/route.tsRepository: superset-sh/superset Length of output: 4632 Validate JWT claim types before constructing Line 20–22 use unchecked casts without runtime narrowing. Although Add runtime type checks for Proposed fix try {
const { payload } = await auth.api.verifyJWT({ body: { token } });
- if (payload?.sub && Array.isArray(payload.organizationIds)) {
+ const userId = typeof payload?.sub === "string" ? payload.sub : null;
+ const email = typeof payload?.email === "string" ? payload.email : "";
+ const organizationIds = Array.isArray(payload?.organizationIds)
+ ? payload.organizationIds.filter(
+ (id): id is string => typeof id === "string",
+ )
+ : [];
+ if (userId) {
return {
- userId: payload.sub,
- email: (payload.email as string) ?? "",
- organizationIds: payload.organizationIds as string[],
+ userId,
+ email,
+ organizationIds,
};
}
} catch {}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Empty (Based on your team's feedback about avoiding empty catch blocks that hide failures.) Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const sessionData = await auth.api.getSession({ headers: request.headers }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!sessionData?.user) return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+12
to
+27
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: find . -type f -name "route.ts" | grep -E "electric.*route\.ts"Repository: superset-sh/superset Length of output: 114 🏁 Script executed: git ls-files | grep "electric.*route\.ts"Repository: superset-sh/superset Length of output: 112 🏁 Script executed: fd "route.ts" apps/apiRepository: superset-sh/superset Length of output: 1650 🏁 Script executed: cat -n apps/api/src/app/api/electric/[...path]/route.tsRepository: superset-sh/superset Length of output: 4632 🏁 Script executed: # Check for Biome configuration and linting
cat biome.json 2>/dev/null || cat .biomeignore 2>/dev/null || echo "No Biome config found"Repository: superset-sh/superset Length of output: 85 🏁 Script executed: # Check if there are any comments or tests explaining the auth fallback behavior
rg -A 5 -B 5 "authenticate.*request" apps/api/src/app/api/electric/[...path]/route.tsRepository: superset-sh/superset Length of output: 701 🏁 Script executed: # Search for similar patterns of empty catch blocks in TypeScript files
rg "catch\s*\{\s*\}" --type ts -C 2 apps/api/src/app/api/electric/Repository: superset-sh/superset Length of output: 337 Return null when Bearer token verification fails—do not fall back to session auth. If an Authorization header with a Bearer token is provided, that signals explicit token-based authentication. When JWT verification fails, silently catching the error and falling back to session auth creates credential-precedence ambiguity. An invalid or malformed token should reject authentication entirely, not degrade to session validation. Proposed fix if (bearer?.startsWith("Bearer ")) {
const token = bearer.slice(7);
try {
const { payload } = await auth.api.verifyJWT({ body: { token } });
if (payload?.sub && Array.isArray(payload.organizationIds)) {
return {
userId: payload.sub,
email: (payload.email as string) ?? "",
organizationIds: payload.organizationIds as string[],
};
}
- } catch {}
+ } catch {
+ return null;
+ }
+ return null;
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| userId: sessionData.user.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| organizationIds: sessionData.session.organizationIds ?? [], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export async function GET(request: Request): Promise<Response> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const sessionData = await auth.api.getSession({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| headers: request.headers, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!sessionData?.user) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const authInfo = await authenticate(request); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!authInfo) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return new Response("Unauthorized", { status: 401 }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const url = new URL(request.url); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Use client-sent organizationId, falling back to session for older clients. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // TODO(2026-02-26): Remove activeOrganizationId fallback once all clients send organizationId param. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const organizationId = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url.searchParams.get("organizationId") ?? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sessionData.session.activeOrganizationId; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const allowedOrgIds = sessionData.session.organizationIds ?? []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const organizationId = url.searchParams.get("organizationId"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (organizationId && !allowedOrgIds.includes(organizationId)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (organizationId && !authInfo.organizationIds.includes(organizationId)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return new Response("Not a member of this organization", { status: 403 }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+42
to
46
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# First, check the structure and find the relevant files
find apps/api/src/app/api/electric -type f -name "*.ts" -o -name "*.tsx" | head -20Repository: superset-sh/superset Length of output: 161 🏁 Script executed: #!/bin/bash
# Check if utils.ts exists and examine buildWhereClause
if [ -f "apps/api/src/app/api/electric/[...path]/utils.ts" ]; then
echo "=== utils.ts found ==="
cat "apps/api/src/app/api/electric/[...path]/utils.ts"
else
echo "=== Searching for utils.ts with fd ==="
fd "utils" apps/api/src/app/api/electric/
fiRepository: superset-sh/superset Length of output: 3743 🏁 Script executed: #!/bin/bash
# Search for buildWhereClause function definition
rg -n "buildWhereClause" apps/api/src/app/api/electric/ -A 15 -B 2Repository: superset-sh/superset Length of output: 4364 🏁 Script executed: #!/bin/bash
# Also check the route.ts file to see the full context
cat -n "apps/api/src/app/api/electric/[...path]/route.ts"Repository: superset-sh/superset Length of output: 3734 🏁 Script executed: #!/bin/bash
# Check if there are any tests or documentation about organizationId requirement
rg -i "organizationId.*required\|optional" apps/api/src/app/api/electric/ -B 2 -A 2Repository: superset-sh/superset Length of output: 46 🏁 Script executed: #!/bin/bash
# Check if there's any validation requiring organizationId elsewhere
rg -n "organizationId" apps/api/src/app/api/electric/\[...path\]/route.ts -B 3 -A 3Repository: superset-sh/superset Length of output: 1168 Require organizationId validation for all endpoints. When
All endpoints should require explicit 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const useCloud = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env.ELECTRIC_SOURCE_ID && | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env.ELECTRIC_SOURCE_SECRET && | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (request.headers.get("x-electric-backend") === "cloud" || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sessionData.user.email?.endsWith("@superset.sh")); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const originUrl = useCloud | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? new URL("/v1/shape", "https://api.electric-sql.cloud") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : new URL(env.ELECTRIC_URL); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (useCloud) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // biome-ignore lint/style/noNonNullAssertion: guarded by useCloud check above | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| originUrl.searchParams.set("source_id", env.ELECTRIC_SOURCE_ID!); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // biome-ignore lint/style/noNonNullAssertion: guarded by useCloud check above | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| originUrl.searchParams.set("secret", env.ELECTRIC_SOURCE_SECRET!); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| originUrl.searchParams.set("secret", env.ELECTRIC_SECRET); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const originUrl = new URL(env.ELECTRIC_URL); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| originUrl.searchParams.set("secret", env.ELECTRIC_SECRET); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url.searchParams.forEach((value, key) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (ELECTRIC_PROTOCOL_QUERY_PARAMS.includes(key)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -57,7 +62,7 @@ export async function GET(request: Request): Promise<Response> { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const whereClause = await buildWhereClause( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tableName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| organizationId ?? "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sessionData.user.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| authInfo.userId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!whereClause) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return new Response(`Unknown table: ${tableName}`, { status: 400 }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -86,8 +91,6 @@ export async function GET(request: Request): Promise<Response> { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const response = await fetch(originUrl.toString()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const headers = new Headers(response.headers); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| headers.append("Vary", "Authorization, X-Electric-Backend"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (headers.get("content-encoding")) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| headers.delete("content-encoding"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| headers.delete("content-length"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| import { FEATURE_FLAGS } from "@superset/shared/constants"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: Setting the Electric URL in Prompt for AI agents |
||
| import { useFeatureFlagEnabled } from "posthog-js/react"; | ||
| import { | ||
| createContext, | ||
| type ReactNode, | ||
|
|
@@ -10,7 +12,11 @@ import { | |
| import { env } from "renderer/env.renderer"; | ||
| import { authClient } from "renderer/lib/auth-client"; | ||
| import { MOCK_ORG_ID } from "shared/constants"; | ||
| import { getCollections, preloadCollections } from "./collections"; | ||
| import { | ||
| getCollections, | ||
| preloadCollections, | ||
| setElectricUrl, | ||
| } from "./collections"; | ||
|
|
||
| type CollectionsContextType = ReturnType<typeof getCollections> & { | ||
| switchOrganization: (organizationId: string) => Promise<void>; | ||
|
|
@@ -34,9 +40,16 @@ export function preloadActiveOrganizationCollections( | |
|
|
||
| export function CollectionsProvider({ children }: { children: ReactNode }) { | ||
| const { data: session, refetch: refetchSession } = authClient.useSession(); | ||
| const useElectricCloud = useFeatureFlagEnabled(FEATURE_FLAGS.ELECTRIC_CLOUD); | ||
| const activeOrganizationId = env.SKIP_ENV_VALIDATION | ||
| ? MOCK_ORG_ID | ||
| : session?.session?.activeOrganizationId; | ||
|
|
||
| useEffect(() => { | ||
| if (useElectricCloud) { | ||
| setElectricUrl(env.NEXT_PUBLIC_ELECTRIC_URL); | ||
| } | ||
| }, [useElectricCloud]); | ||
|
Comment on lines
+48
to
+52
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# First, let's find and examine the collections.ts file
fd "collections.ts" apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/
# Check the setElectricUrl function
rg -n "setElectricUrl" apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/ -A 5 -B 2
# Check how electricUrl is used
rg -n "electricUrl" apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/ -A 2 -B 2Repository: superset-sh/superset Length of output: 13404 🏁 Script executed: #!/bin/bash
# Find where getCollections is called in the CollectionsProvider
rg -n "getCollections" apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx -B 2 -A 2
# Check the getCollections function implementation and how it uses electricUrl
rg -n "export function getCollections" apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts -A 30
# Check if shapes are created lazily or at module load time
rg -n "const shapes" apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts -B 2 -A 20Repository: superset-sh/superset Length of output: 997 🏁 Script executed: #!/bin/bash
# Get full context around line 74 to see what hook/function contains it
sed -n '60,90p' apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx
# Find and examine createOrgCollections
rg -n "function createOrgCollections" apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts -A 40Repository: superset-sh/superset Length of output: 2244 Potential race condition: Electric shapes may be created before URL is updated. When Ensure 🤖 Prompt for AI Agents |
||
| const [isSwitching, setIsSwitching] = useState(false); | ||
|
|
||
| const switchOrganization = useCallback( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 638
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 170
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 4899
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 117
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 155
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 458
🏁 Script executed:
# Check the src directory structure to understand what the Worker does ls -la apps/electric-proxy/src/Repository: superset-sh/superset
Length of output: 467
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 155
🏁 Script executed:
# Check if there are comments or setup docs in the electric-proxy package.json or README cat apps/electric-proxy/package.jsonRepository: superset-sh/superset
Length of output: 612
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 46
🏁 Script executed:
# Check the index.ts to see how environment variables are being used head -50 apps/electric-proxy/src/index.tsRepository: superset-sh/superset
Length of output: 1642
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 252
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 148
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 866
🏁 Script executed:
# Check if there's environment binding configuration later in wrangler.jsonc or if it's complete wc -l apps/electric-proxy/wrangler.jsoncRepository: superset-sh/superset
Length of output: 100
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 589
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 98
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 1181
🏁 Script executed:
# Check how AUTH_URL is currently being handled - is it in wrangler.jsonc with bindings? cat -n apps/electric-proxy/wrangler.jsoncRepository: superset-sh/superset
Length of output: 190
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 1188
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 1014
Add required Worker environment variables to the deployment command.
The
wrangler.jsoncfile (notwrangler.toml) exists and is valid, but it lacks environment bindings. The deploy step must pass Worker environment variables during deployment since they are required at runtime. The Worker code requiresAUTH_URL(mandatory) and expects optional variables likeELECTRIC_URLandELECTRIC_SECRETdefined in theEnvinterface.Update the deploy step to either:
wrangler.jsoncwith a[env.production]section, orEnsure the corresponding GitHub secrets (
AUTH_URL,ELECTRIC_URL,ELECTRIC_SECRET) are configured in the production environment.🤖 Prompt for AI Agents