mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
**Stack 1/6** of the TanStack Start migration (#46424), split into reviewable, independently-mergeable PRs. > [!IMPORTANT] > **Next stays the default and only active framework after this PR.** This wires up the Vite/TanStack-Start build pipeline behind the `STUDIO_FRAMEWORK` flag, but there are no TanStack routes yet — so the TanStack build isn't functional or tested until later PRs in the stack. Nothing about the Next build, dev, or deploy changes behaviourally here. ## What's in this PR - **Dispatch:** `dev`/`build`/`start` now go through `scripts/dispatch.js`, which runs the Next variant unless `STUDIO_FRAMEWORK=tanstack`. The original commands are preserved as `dev:next`/`build:next`/`start:next`. - **Build pipeline:** `vite.config.ts`, `serve.js`, `smoke-server.mjs`, vite/tanstack deps, `turbo.jsonc`. - **`tsconfig.json`:** `jsx: react-jsx`, `moduleResolution: Bundler`, `target: ES2022`. Because `include` is `**/*.ts(x)`, this re-typechecks the whole app, so the companion adaptations below land with it. - **Shared adaptations (companions to the tsconfig change):** `BufferSource` casts, `packages/ui` unused-`React` import removals, etc. - **Routing/middleware plumbing:** `next.config.ts` + `redirects.shared.ts` (redirect rules now shared with `vercel.ts`), `proxy.ts`/`start.ts` middleware + `hosted-api-allowlist.ts`. ## Verification Run locally off `master`: frozen install ✓, `studio` typecheck ✓, **Next build ✓** (compiles + generates all routes), lint ratchet ✓ ("some rules improved"), prettier ✓. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a hosted API endpoint allowlist to return 404 for non-supported `/api/*` routes. * Introduced a TanStack route-migration checklist and expanded TanStack Start routing support. * **Improvements** * Enhanced deployment refresh/detection by tightening cookie handling for “latest deployment” updates. * Centralized redirect/maintenance-mode rules for consistent platform vs self-hosted behavior. * Improved production serving with a dedicated static + proxy server and a post-build smoke test. * **Dependencies** * Updated TanStack-related packages and React Table/query tooling versions. * **Documentation / Chores** * Updated formatting and tooling config; added shared build environment parsing utilities. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
54 lines
1.5 KiB
TypeScript
54 lines
1.5 KiB
TypeScript
/**
|
|
* LLMs sometimes emit MySQL-style `\'` escapes in SQL. PostgreSQL doesn't
|
|
* treat backslash as an escape character, so replace `\'` → `''`.
|
|
* Dollar-quoted strings (e.g. `$$...$$`) are left untouched.
|
|
*/
|
|
export function fixSqlBackslashEscapes(sql: string): string {
|
|
return sql.replace(/\$([^$]*)\$[\s\S]*?\$\1\$|\\'/g, (match, dollarTag) =>
|
|
dollarTag !== undefined ? match : "''"
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Selects a key from weighted choices using consistent hashing
|
|
* on an input string.
|
|
*
|
|
* The same input always returns the same key, with distribution
|
|
* proportional to the provided weights.
|
|
*
|
|
* @example
|
|
* const region = await selectWeightedKey('my-unique-id', {
|
|
* use1: 40,
|
|
* use2: 10,
|
|
* usw2: 10,
|
|
* euc1: 10,
|
|
* })
|
|
* // Returns one of the keys based on the input and weights
|
|
*/
|
|
export async function selectWeightedKey<T extends string>(
|
|
input: string,
|
|
weights: Record<T, number>
|
|
): Promise<T> {
|
|
const keys = Object.keys(weights) as T[]
|
|
const encoder = new TextEncoder()
|
|
const data = encoder.encode(input)
|
|
const hashBuffer = await crypto.subtle.digest('SHA-256', data as BufferSource)
|
|
|
|
// Use first 4 bytes (32 bit integer)
|
|
const hashInt = new DataView(hashBuffer).getUint32(0)
|
|
|
|
const totalWeight = keys.reduce((sum, key) => sum + weights[key], 0)
|
|
|
|
let cumulativeWeight = 0
|
|
const targetWeight = hashInt % totalWeight
|
|
|
|
for (const key of keys) {
|
|
cumulativeWeight += weights[key]
|
|
if (cumulativeWeight > targetWeight) {
|
|
return key
|
|
}
|
|
}
|
|
|
|
return keys[0]
|
|
}
|