Files
supabase/apps/studio/components/ui/SafeSqlInput.tsx
Charis 2d2cc95caa studio: add SafeSql foundation utilities (1/7) (#45897)
## Summary

First in a stack of seven PRs migrating the remaining `executeSql` call
sites to `SafeSqlFragment`. This PR lands pure additions — shared types
and helpers that later PRs import.

- `apps/studio/lib/postgres-types.ts` — `SafePostgresColumn` /
`SafePostgresTable` wrappers over `PGColumn` / `PGTable` that brand
`check` as `SafeSqlFragment` and add the optional `format_schema` field
- `apps/studio/lib/sql.ts` — `trimSafeSqlFragment` overload set that
preserves the brand through `.trim()`
- `apps/studio/lib/type-helpers.ts` — refine `DeepReadonly` so
primitives pass through unchanged
- `apps/studio/components/ui/SafeSqlInput.tsx` — `<Input>` wrapper that
emits `SafeSqlFragment` via `rawSql`

No consumers in this PR. The next PRs in the stack pick these up.

## Stack

This is PR 1 of 7. The full sequence:

1. **This PR** — Foundation utilities
2. `charis/safe-sql-last/2` — pg-meta columns + ColumnTypeRef cascade
3. `charis/safe-sql-last/3` — pg-meta non-column SafeSql
(functions/policies/triggers)
4. `charis/safe-sql-last/4` — Studio reports / query performance /
privileges
5. `charis/safe-sql-last/6` — Stragglers + remaining tests
6. `charis/safe-sql-last/7` — Flip `executeSql` signature from `string`
to `SafeSqlFragment`

## Test plan

- [x] `pnpm typecheck` passes for the Studio target on this branch
- [x] No runtime behavior changes — only type-level additions and a new
unused component

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **New Features**
* Introduced SafeSqlInput component providing secure and validated SQL
query input handling with built-in constraints and error prevention.

* **Refactor**
* Enhanced internal type definitions and utilities for Postgres metadata
handling and SQL operations to improve code reliability and
maintainability.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45897)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-13 14:57:08 -04:00

16 lines
629 B
TypeScript

import { rawSql, type SafeSqlFragment } from '@supabase/pg-meta'
import type { ChangeEvent, ComponentProps } from 'react'
import { Input } from 'ui-patterns/DataInputs/Input'
type InputProps = ComponentProps<typeof Input>
export type SafeSqlInputProps = Omit<InputProps, 'placeholder' | 'value' | 'onChange'> & {
placeholder?: SafeSqlFragment
value: SafeSqlFragment
onChange?: (event: ChangeEvent<HTMLInputElement>, value: SafeSqlFragment) => void
}
export const SafeSqlInput = ({ onChange, ...props }: SafeSqlInputProps) => (
<Input {...props} onChange={(event) => onChange?.(event, rawSql(event.target.value))} />
)