mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
docs: update reference rendering files (#43587)
Update reference rendering files to support additional values in tsdoc. --------- Co-authored-by: Jonathan Summers-Muir <MildTomato@users.noreply.github.com>
This commit is contained in:
1 parent
54ac9fff25
commit
01ca9bc375
8 files changed
+246
-42
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { isFeatureEnabled } from 'common'
|
||||
import { Fragment, type PropsWithChildren } from 'react'
|
||||
import { type PropsWithChildren } from 'react'
|
||||
|
||||
import { cn } from 'ui'
|
||||
|
||||
@@ -43,19 +43,17 @@ export async function ReferenceNavigation({
|
||||
<RefVersionDropdown library={libPath} currentVersion={version} />
|
||||
</div>
|
||||
<ul className="flex flex-col gap-2">
|
||||
{displayedNavSections?.map((section) => (
|
||||
<Fragment key={section.id}>
|
||||
{section.type === 'category' ? (
|
||||
<li>
|
||||
<RefCategory basePath={basePath} section={section} />
|
||||
</li>
|
||||
) : (
|
||||
<li className={topLvlRefNavItemStyles}>
|
||||
<RefLink basePath={basePath} section={section} />
|
||||
</li>
|
||||
)}
|
||||
</Fragment>
|
||||
))}
|
||||
{displayedNavSections?.map((section, index) =>
|
||||
section.type === 'category' ? (
|
||||
<li key={section.id ?? String(index)}>
|
||||
<RefCategory basePath={basePath} section={section} />
|
||||
</li>
|
||||
) : (
|
||||
<li key={section.id ?? String(index)} className={topLvlRefNavItemStyles}>
|
||||
<RefLink basePath={basePath} section={section} />
|
||||
</li>
|
||||
)
|
||||
)}
|
||||
</ul>
|
||||
</ReferenceNavigationScrollHandler>
|
||||
)
|
||||
|
||||
@@ -467,6 +467,7 @@ async function FunctionSection({
|
||||
|
||||
const fullDescription = [
|
||||
types?.comment?.shortText,
|
||||
types?.comment?.text,
|
||||
'description' in fn && (fn.description as string),
|
||||
'notes' in fn && (fn.notes as string),
|
||||
]
|
||||
@@ -549,7 +550,6 @@ async function FunctionSection({
|
||||
<TabsContent_Shadcn_ key={example.id} value={example.id}>
|
||||
<MDXRemoteRefs source={example.code} />
|
||||
<div className="flex flex-col gap-2 mt-2">
|
||||
{/* Only YAML examples have data/response/description fields */}
|
||||
{'data' in example && !!example.data?.sql && (
|
||||
<CollapsibleDetails title="Data source" content={example.data.sql} />
|
||||
)}
|
||||
|
||||
@@ -58,7 +58,14 @@ interface Comment {
|
||||
shortText?: string
|
||||
text?: string
|
||||
tags?: Array<{ tag: string; text: string }>
|
||||
examples?: Array<{ id: string; name: string; code: string; response?: string }>
|
||||
examples?: Array<{
|
||||
id: string
|
||||
name: string
|
||||
code: string
|
||||
description?: string
|
||||
response?: string
|
||||
data?: { sql: string }
|
||||
}>
|
||||
}
|
||||
|
||||
export interface FunctionParameterType {
|
||||
@@ -242,33 +249,75 @@ function normalizeComment(original: TypedocComment | Comment | undefined): Comme
|
||||
comment.tags = original.modifierTags.map((tag) => ({ tag: tag.replace(/^@/, ''), text: '' }))
|
||||
}
|
||||
|
||||
if ('blockTags' in original && Array.isArray(original.blockTags)) {
|
||||
const remarksTag = original.blockTags.find((t) => t.tag === '@remarks')
|
||||
if (remarksTag) {
|
||||
comment.text = remarksTag.content.map((p) => p.text).join('')
|
||||
}
|
||||
}
|
||||
|
||||
// Extract @example tags from blockTags
|
||||
if ('blockTags' in original && Array.isArray(original.blockTags)) {
|
||||
const exampleTags = original.blockTags.filter((tag) => tag.tag === '@example')
|
||||
const exampleTags = original.blockTags.filter((t) => t.tag === '@example')
|
||||
// Helper: companion tags (e.g. @exampleDescription) may have no TypeDoc
|
||||
// `name` field; the example name is then the first line of content.
|
||||
function deconstructTag(t: CommentBlockTag): [name: string, body: string] {
|
||||
if (t.name) {
|
||||
return [t.name, t.content.map((p) => p.text).join('')]
|
||||
}
|
||||
const first = t.content[0]
|
||||
// TypeDoc may produce a tag with an empty content array (e.g. a tag with
|
||||
// no body text). Guard here so the rest of the parsing can safely assume
|
||||
// a non-empty first element.
|
||||
if (!first) return ['', '']
|
||||
const newline = first.text.indexOf('\n')
|
||||
const name = (newline >= 0 ? first.text.slice(0, newline) : first.text).trim()
|
||||
const tail = newline >= 0 ? first.text.slice(newline + 1) : ''
|
||||
const body = [{ ...first, text: tail }, ...t.content.slice(1)].map((p) => p.text).join('')
|
||||
return [name, body]
|
||||
}
|
||||
|
||||
const descByName = Object.fromEntries(
|
||||
original.blockTags
|
||||
.filter((t) => t.tag === '@exampleDescription')
|
||||
.map((t) => deconstructTag(t))
|
||||
)
|
||||
const sqlByName = Object.fromEntries(
|
||||
original.blockTags.filter((t) => t.tag === '@exampleSql').map((t) => deconstructTag(t))
|
||||
)
|
||||
const respByName = Object.fromEntries(
|
||||
original.blockTags.filter((t) => t.tag === '@exampleResponse').map((t) => deconstructTag(t))
|
||||
)
|
||||
|
||||
if (exampleTags.length > 0) {
|
||||
comment.examples = exampleTags.map((tag, index) => {
|
||||
// Use the name if provided, otherwise generate a default name
|
||||
const name = tag.name || `Example ${index + 1}`
|
||||
// Convert name to kebab-case for id
|
||||
const id = name
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/^-|-$/g, '')
|
||||
// Join content to get the full text
|
||||
const fullText = tag.content.map((part) => part.text).join('')
|
||||
const fullCode = tag.content.map((p) => p.text).join('')
|
||||
|
||||
// Check if there's a "Response:" section and split it
|
||||
const responseMatch = fullText.match(/\n\s*Response:\s*\n/i)
|
||||
let code = fullText
|
||||
let response: string | undefined = undefined
|
||||
|
||||
if (responseMatch) {
|
||||
const splitIndex = responseMatch.index! + responseMatch[0].length
|
||||
code = fullText.substring(0, responseMatch.index!).trim()
|
||||
response = fullText.substring(splitIndex).trim()
|
||||
// Prefer structured @exampleResponse tag; fall back to legacy inline "Response:" split
|
||||
// for methods not yet migrated to the new JSDoc format.
|
||||
let code = fullCode
|
||||
let response: string | undefined = respByName[name] || undefined
|
||||
if (!response) {
|
||||
const match = fullCode.match(/\n\nResponse:\n/)
|
||||
if (match && match.index !== undefined) {
|
||||
code = fullCode.slice(0, match.index)
|
||||
response = fullCode.slice(match.index + match[0].length)
|
||||
}
|
||||
}
|
||||
|
||||
return { id, name, code, response }
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
code,
|
||||
description: descByName[name] || undefined,
|
||||
data: sqlByName[name] ? { sql: sqlByName[name] } : undefined,
|
||||
response,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -487,7 +536,13 @@ function parseMethod(
|
||||
const signature = node.signatures[0]
|
||||
if (!signature) return
|
||||
|
||||
const { params, ret, comment } = parseSignature(signature, map)
|
||||
let { params, ret, comment } = parseSignature(signature, map)
|
||||
|
||||
// When a method has multiple overload signatures, TypeDoc places the shared
|
||||
// JSDoc on the method node rather than any individual signature.
|
||||
if (!comment && node.comment) {
|
||||
comment = normalizeComment(node.comment)
|
||||
}
|
||||
|
||||
const types: MethodTypes = {
|
||||
name: $ref,
|
||||
|
||||
@@ -8968,6 +8968,7 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Updates the user data. Changes are applied directly without confirmation flows.",
|
||||
"text": "**Important:** This is a server-side operation and does **not** trigger client-side\\n\`onAuthStateChange\` listeners. The admin API has no connection to client state.\\n\\nTo sync changes to the client after calling this method:\\n1. On the client, call \`supabase.auth.refreshSession()\` to fetch the updated user data\\n2. This will trigger the \`TOKEN_REFRESHED\` event and notify all listeners",
|
||||
"examples": [
|
||||
{
|
||||
"id": "example-1",
|
||||
@@ -42569,6 +42570,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "PostgrestQueryBuilder"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Perform a query on a table or a view."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -52471,6 +52475,7 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Updates the user data. Changes are applied directly without confirmation flows.",
|
||||
"text": "**Important:** This is a server-side operation and does **not** trigger client-side\\n\`onAuthStateChange\` listeners. The admin API has no connection to client state.\\n\\nTo sync changes to the client after calling this method:\\n1. On the client, call \`supabase.auth.refreshSession()\` to fetch the updated user data\\n2. This will trigger the \`TOKEN_REFRESHED\` event and notify all listeners",
|
||||
"examples": [
|
||||
{
|
||||
"id": "example-1",
|
||||
@@ -79916,6 +79921,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "PostgrestQueryBuilder"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Perform a query on a table or a view."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -80352,6 +80360,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Only relevant for jsonb, array, and range columns. Match only rows where\\nevery element appearing in \`column\` is contained by \`value\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -80451,6 +80462,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Only relevant for jsonb, array, and range columns. Match only rows where\\n\`column\` contains every element appearing in \`value\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -80790,6 +80804,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows which satisfy the filter. This is an escape hatch - you\\nshould use the specific filter methods wherever possible.\\n\\nUnlike most filters, \`opearator\` and \`value\` are used as-is and need to\\nfollow [PostgREST\\nsyntax](https://postgrest.org/en/stable/api.html#operators). You also need\\nto make sure they are properly sanitized."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -80861,6 +80878,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` is greater than \`value\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -80912,6 +80932,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` is greater than or equal to \`value\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -80963,6 +80986,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` matches \`pattern\` case-insensitively."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -81017,6 +81043,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` matches all of \`patterns\` case-insensitively."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -81074,6 +81103,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` matches any of \`patterns\` case-insensitively."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -81157,6 +81189,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` IS \`value\`.\\n\\nFor non-boolean columns, this is only relevant for checking if the value of\\n\`column\` is NULL by setting \`value\` to \`null\`.\\n\\nFor boolean columns, you can also set \`value\` to \`true\` or \`false\` and it\\nwill behave the same way as \`.eq()\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -81247,6 +81282,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` matches \`pattern\` case-sensitively."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -81301,6 +81339,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` matches all of \`patterns\` case-sensitively."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -81358,6 +81399,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` matches any of \`patterns\` case-sensitively."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -81469,6 +81513,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` is less than \`value\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -81520,6 +81567,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` is less than or equal to \`value\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -81572,6 +81622,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where each column in \`query\` keys is equal to its\\nassociated value. Shorthand for multiple \`.eq()\`s."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -81692,6 +81745,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows which doesn't satisfy the filter.\\n\\nUnlike most filters, \`opearator\` and \`value\` are used as-is and need to\\nfollow [PostgREST\\nsyntax](https://postgrest.org/en/stable/api.html#operators). You also need\\nto make sure they are properly sanitized."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -81866,6 +81922,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Order the query result by \`column\`.\\n\\nYou can call this method multiple times to order by multiple columns.\\n\\nYou can order referenced tables, but it only affects the ordering of the\\nparent table if you use \`!inner\` in the query."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -82061,6 +82120,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Only relevant for array and range columns. Match only rows where\\n\`column\` and \`value\` have an element in common."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -82211,6 +82273,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Only relevant for range columns. Match only rows where \`column\` is\\nmutually exclusive to \`range\` and there can be no element between the two\\nranges."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -82262,6 +82327,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Only relevant for range columns. Match only rows where every element in\\n\`column\` is greater than any element in \`range\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -82313,6 +82381,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Only relevant for range columns. Match only rows where every element in\\n\`column\` is either contained in \`range\` or greater than any element in\\n\`range\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -82364,6 +82435,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Only relevant for range columns. Match only rows where every element in\\n\`column\` is less than any element in \`range\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -82415,6 +82489,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Only relevant for range columns. Match only rows where every element in\\n\`column\` is either contained in \`range\` or less than any element in\\n\`range\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -82466,6 +82543,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` matches the PostgreSQL regex \`pattern\`\\ncase-insensitively (using the \`~*\` operator)."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -82517,6 +82597,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Match only rows where \`column\` matches the PostgreSQL regex \`pattern\`\\ncase-sensitively (using the \`~\` operator)."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -82698,6 +82781,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Only relevant for text and tsvector columns. Match only rows where\\n\`column\` matches the query string in \`query\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -83164,6 +83250,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "PostgrestFilterBuilder"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Perform an INSERT into the table or view.\\n\\nBy default, inserted rows are not returned. To return it, chain the call\\nwith \`.select()\`."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -83294,7 +83383,8 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Perform a SELECT query on the table or view."
|
||||
"shortText": "Perform a SELECT query on the table or view.",
|
||||
"text": "When using \`count\` with \`.range()\` or \`.limit()\`, the returned \`count\` is the total number of rows\\nthat match your filters, not the number of rows in the current page. Use this to build pagination UI."
|
||||
}
|
||||
},
|
||||
"@supabase/postgrest-js.PostgrestQueryBuilder.update": {
|
||||
@@ -83419,6 +83509,21 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "PostgrestFilterBuilder"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Perform an UPSERT on the table or view. Depending on the column(s) passed\\nto \`onConflict\`, \`.upsert()\` allows you to perform the equivalent of\\n\`.insert()\` if a row with the corresponding \`onConflict\` columns doesn't\\nexist, or if it does exist, perform an alternative action depending on\\n\`ignoreDuplicates\`.\\n\\nBy default, upserted rows are not returned. To return it, chain the call\\nwith \`.select()\`.",
|
||||
"examples": [
|
||||
{
|
||||
"id": "upsert-a-single-row-using-a-unique-key",
|
||||
"name": "Upsert a single row using a unique key",
|
||||
"code": "\`\`\`ts\\n// Upserting a single row, overwriting based on the 'username' unique column\\nconst { data, error } = await supabase\\n .from('users')\\n .upsert({ username: 'supabot' }, { onConflict: 'username' })\\n\\n// Example response:\\n// {\\n// data: [\\n// { id: 4, message: 'bar', username: 'supabot' }\\n// ],\\n// error: null\\n// }\\n\`\`\`"
|
||||
},
|
||||
{
|
||||
"id": "upsert-with-conflict-resolution-and-exact-row-counting",
|
||||
"name": "Upsert with conflict resolution and exact row counting",
|
||||
"code": "\`\`\`ts\\n// Upserting and returning exact count\\nconst { data, error, count } = await supabase\\n .from('users')\\n .upsert(\\n {\\n id: 3,\\n message: 'foo',\\n username: 'supabot'\\n },\\n {\\n onConflict: 'username',\\n count: 'exact'\\n }\\n )\\n\\n// Example response:\\n// {\\n// data: [\\n// {\\n// id: 42,\\n// handle: \\"saoirse\\",\\n// display_name: \\"Saoirse\\"\\n// }\\n// ],\\n// count: 1,\\n// error: null\\n// }\\n\`\`\`"
|
||||
}
|
||||
]
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -83958,6 +84063,9 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"name": "this"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"shortText": "Order the query result by \`column\`.\\n\\nYou can call this method multiple times to order by multiple columns.\\n\\nYou can order referenced tables, but it only affects the ordering of the\\nparent table if you use \`!inner\` in the query."
|
||||
},
|
||||
"altSignatures": [
|
||||
{
|
||||
"params": [
|
||||
@@ -90090,6 +90198,7 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
|
||||
"text": ""
|
||||
}
|
||||
],
|
||||
"text": "This method provides a bridge between Supabase's bucket management and the standard\\nApache Iceberg REST Catalog API. The bucket name maps to the Iceberg warehouse parameter.\\nAll authentication and configuration is handled automatically using your Supabase credentials.\\n\\n**Error Handling**: Invalid bucket names throw immediately. All catalog\\noperations return \`{ data, error }\` where errors are \`IcebergError\` instances from iceberg-js.\\nUse helper methods like \`error.isNotFound()\` or check \`error.status\` for specific error handling.\\nUse \`.throwOnError()\` on the analytics client if you prefer exceptions for catalog operations.\\n\\n**Cleanup Operations**: When using \`dropTable\`, the \`purge: true\` option permanently\\ndeletes all table data. Without it, the table is marked as deleted but data remains.\\n\\n**Library Dependency**: The returned catalog wraps \`IcebergRestCatalog\` from iceberg-js.\\nFor complete API documentation and advanced usage, refer to the\\n[iceberg-js documentation](https://supabase.github.io/iceberg-js/).",
|
||||
"examples": [
|
||||
{
|
||||
"id": "get-catalog-and-create-table",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useSearchParamsShallow } from 'common'
|
||||
import { xor } from 'lodash'
|
||||
import { Children, useEffect, useRef, type FC, type PropsWithChildren } from 'react'
|
||||
import { Children, isValidElement, useEffect, useRef, type FC, type PropsWithChildren } from 'react'
|
||||
import { type TabsProps } from 'ui'
|
||||
|
||||
const isString = (maybeStr: unknown): maybeStr is string => typeof maybeStr === 'string'
|
||||
@@ -27,10 +27,14 @@ const withQueryParams =
|
||||
onClick,
|
||||
...props
|
||||
}: Props & QueryParamsProps) => {
|
||||
const children = Children.toArray(childrenUnvalidated)
|
||||
const tabIdsTemp = children
|
||||
.map((child) => !!child && typeof child === 'object' && 'props' in child && child.props.id)
|
||||
.filter(isString)
|
||||
// Avoid Children.toArray — it clones elements (accessing element.ref) which
|
||||
// triggers a React 19 warning. Children.forEach iterates without cloning.
|
||||
const tabIdsTemp: string[] = []
|
||||
Children.forEach(childrenUnvalidated, (child) => {
|
||||
if (isValidElement(child) && isString((child.props as any).id)) {
|
||||
tabIdsTemp.push((child.props as any).id)
|
||||
}
|
||||
})
|
||||
// Store in ref to avoid stale data in later timeout
|
||||
const tabIdsRef = useRef(tabIdsTemp)
|
||||
tabIdsRef.current = tabIdsTemp
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
"@radix-ui/react-slider": "^1.3.6",
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
"@radix-ui/react-switch": "^1.0.3",
|
||||
"@radix-ui/react-tabs": "^1.0.4",
|
||||
"@radix-ui/react-tabs": "^1.1.0",
|
||||
"@radix-ui/react-toggle": "^1.1.10",
|
||||
"@radix-ui/react-toggle-group": "^1.1.11",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import * as TabsPrimitive from '@radix-ui/react-tabs'
|
||||
import {
|
||||
Children,
|
||||
isValidElement,
|
||||
useMemo,
|
||||
useState,
|
||||
type KeyboardEvent,
|
||||
@@ -58,7 +59,15 @@ const Tabs: React.FC<PropsWithChildren<TabsProps>> & TabsSubComponents = ({
|
||||
refs,
|
||||
children: _children,
|
||||
}) => {
|
||||
const children = Children.toArray(_children) as PanelPropsProps[]
|
||||
// Children.toArray clones elements (to assign keys) and accesses element.ref
|
||||
// internally, which triggers a React 19 warning. Children.forEach iterates
|
||||
// without cloning, so it never touches .ref
|
||||
// todo: remove this when we upgrade the radix packages to support react 19
|
||||
const childrenArr: PanelPropsProps[] = []
|
||||
Children.forEach(_children, (child) => {
|
||||
if (isValidElement(child)) childrenArr.push(child as unknown as PanelPropsProps)
|
||||
})
|
||||
const children = childrenArr
|
||||
|
||||
const [activeTab, setActiveTab] = useState(
|
||||
activeId ??
|
||||
|
||||
Generated
+31
-2
@@ -2409,8 +2409,8 @@ importers:
|
||||
specifier: ^1.0.3
|
||||
version: 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-tabs':
|
||||
specifier: ^1.0.4
|
||||
version: 1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.13(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-toggle':
|
||||
specifier: ^1.1.10
|
||||
version: 1.1.10(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -7119,6 +7119,19 @@ packages:
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
|
||||
'@radix-ui/react-tabs@1.1.13':
|
||||
resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
|
||||
'@radix-ui/react-toast@1.2.14':
|
||||
resolution: {integrity: sha512-nAP5FBxBJGQ/YfUB+r+O6USFVkWq3gAInkxyEnmvEV5jtSbfDhfa4hwX8CraCnbjMLsE7XSf/K75l9xXY7joWg==}
|
||||
peerDependencies:
|
||||
@@ -24221,6 +24234,22 @@ snapshots:
|
||||
'@types/react': 18.3.3
|
||||
'@types/react-dom': 18.3.0
|
||||
|
||||
'@radix-ui/react-tabs@1.1.13(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@radix-ui/primitive': 1.1.3
|
||||
'@radix-ui/react-context': 1.1.2(@types/react@18.3.3)(react@18.3.1)
|
||||
'@radix-ui/react-direction': 1.1.1(@types/react@18.3.3)(react@18.3.1)
|
||||
'@radix-ui/react-id': 1.1.1(@types/react@18.3.3)(react@18.3.1)
|
||||
'@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.3)(react@18.3.1)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.3
|
||||
'@types/react-dom': 18.3.0
|
||||
|
||||
'@radix-ui/react-toast@1.2.14(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@radix-ui/primitive': 1.1.2
|
||||
|
||||
Reference in new issue
Block a user