diff --git a/apps/docs/app/api/crawlers/route.test.ts b/apps/docs/app/api/crawlers/route.test.ts new file mode 100644 index 00000000000..d25fd4b3551 --- /dev/null +++ b/apps/docs/app/api/crawlers/route.test.ts @@ -0,0 +1,125 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' + +const reference = vi.hoisted(() => ({ + sections: [] as Array<{ id: string; slug: string; title: string; type: string }>, +})) + +vi.mock('~/features/docs/Reference.generated.singleton', () => ({ + getFlattenedSections: async () => reference.sections, + getFunctionsList: async () => [], + getTypeSpec: async () => undefined, +})) + +vi.mock('~/features/docs/Reference.mdx', () => ({ + getRefMarkdown: async () => 'Reference content', +})) + +vi.mock('next/navigation', () => ({ + notFound: () => { + throw new Error('notFound') + }, +})) + +import { GET } from './route' + +function section(slug: string, title: string, type = 'markdown') { + return { id: slug, slug, title, type } +} + +async function html(path: string) { + const response = await GET(new Request(`https://supabase.com${path}`)) + expect(response.status).toBe(200) + return response.text() +} + +beforeEach(() => { + reference.sections = [] +}) + +describe('crawler reference aliases', () => { + it('resolves unique bare JavaScript modifier and filter slugs', async () => { + reference.sections = [ + section('using-modifiers-order', 'Order'), + section('using-filters-or', 'Or'), + section('using-modifiers-maybesingle', 'Maybe single'), + ] + + for (const [requested, canonical] of [ + ['order', 'using-modifiers-order'], + ['or', 'using-filters-or'], + ['maybeSingle', 'using-modifiers-maybesingle'], + ]) { + expect(await html(`/reference/javascript/${requested}`)).toContain( + `href="https://supabase.com/docs/reference/javascript/${canonical}"` + ) + } + }) + + it('resolves storage slugs and keeps an exact versioned slug', async () => { + reference.sections = [ + section('file-buckets-createbucket', 'Create bucket'), + section('file-buckets-upload', 'Upload'), + section('file-buckets-createsignedurl', 'Create signed URL'), + section('file-buckets-updatebucket', 'Update bucket'), + section('file-buckets-listv2', 'List files v2'), + ] + + for (const [requested, canonical] of [ + ['storage-createbucket', 'file-buckets-createbucket'], + ['storage-from-upload', 'file-buckets-upload'], + ['storage-from-createsignedurl', 'file-buckets-createsignedurl'], + ['storage-updatebucket', 'file-buckets-updatebucket'], + ['file-buckets-listv2', 'file-buckets-listv2'], + ]) { + expect(await html(`/reference/javascript/${requested}`)).toContain( + `href="https://supabase.com/docs/reference/javascript/${canonical}"` + ) + } + }) + + it('resolves SDK-specific user and root aliases', async () => { + reference.sections = [ + section('introduction', 'Introduction'), + section('auth-admin', 'Admin'), + section('auth-getuser', 'Get user'), + section('auth-currentuser', 'Current user'), + ] + + expect(await html('/reference/javascript')).toContain( + 'href="https://supabase.com/docs/reference/javascript/introduction"' + ) + expect(await html('/reference/javascript/start')).toContain('JavaScript: Introduction') + expect(await html('/reference/javascript/admin-api')).toContain('JavaScript: Admin') + expect(await html('/reference/swift/get-user')).toContain( + 'href="https://supabase.com/docs/reference/swift/auth-getuser"' + ) + expect(await html('/reference/dart/get-user')).toContain( + 'href="https://supabase.com/docs/reference/dart/auth-currentuser"' + ) + expect(await html('/reference/kotlin')).toContain('Kotlin: Introduction') + }) + + it('keeps exact matches ahead of aliases and rejects ambiguous bare slugs', async () => { + reference.sections = [ + section('delete', 'Delete'), + section('auth-passkey-list', 'Passkeys'), + section('file-buckets-list', 'Files'), + ] + + expect(await html('/reference/javascript/delete')).toContain('JavaScript: Delete') + expect(await html('/reference/javascript/storage-list')).toContain('JavaScript: Files') + await expect(html('/reference/javascript/list')).rejects.toThrow('notFound') + }) + + it('uses canonical paths for explicit versions', async () => { + reference.sections = [section('auth-update', 'Update')] + + expect(await html('/reference/javascript/v1/auth-update')).toContain( + 'href="https://supabase.com/docs/reference/javascript/v1/auth-update"' + ) + reference.sections = [section('auth-updateuser', 'Update')] + expect(await html('/reference/javascript/v2/auth-updateuser')).toContain( + 'href="https://supabase.com/docs/reference/javascript/auth-updateuser"' + ) + }) +}) diff --git a/apps/docs/app/api/crawlers/route.ts b/apps/docs/app/api/crawlers/route.ts index 568ee6588b0..cfa75bf2af9 100644 --- a/apps/docs/app/api/crawlers/route.ts +++ b/apps/docs/app/api/crawlers/route.ts @@ -43,10 +43,23 @@ export async function GET(request: Request) { url, } }) - section = flattenedSections.find( - (section) => - (section.type === 'markdown' || section.type === 'function') && section.slug === slug + const contentSections = flattenedSections.filter( + (section) => section.type === 'markdown' || section.type === 'function' ) + section = contentSections.find((section) => section.slug === slug) + if (!section) { + const legacySlug = slug?.toLowerCase() + const replacement = legacyReferenceSlug(lib, version, legacySlug) + + if (replacement) { + section = contentSections.find((section) => section.slug?.toLowerCase() === replacement) + } else if (legacySlug && version === 'v2' && (lib === 'javascript' || lib === 'dart')) { + const matches = contentSections.filter((section) => + section.slug?.toLowerCase().endsWith(`-${legacySlug}`) + ) + if (matches.length === 1) section = matches[0] + } + } } catch {} if (!section) { @@ -56,7 +69,7 @@ export async function GET(request: Request) { const html = htmlShell( lib, isVersion ? version : null, - slug, + section.slug ?? slug, section, libraryNav(sectionsWithUrl) + (await sectionDetails(lib, isVersion ? version : null, section)) ) @@ -66,6 +79,17 @@ export async function GET(request: Request) { return response } +function legacyReferenceSlug(lib: string, version: string, slug?: string) { + if (!slug || slug === 'start') return 'introduction' + if (lib === 'swift' && version === 'v2' && slug === 'get-user') return 'auth-getuser' + if (version !== 'v2' || (lib !== 'javascript' && lib !== 'dart')) return undefined + if (slug === 'admin-api') return 'auth-admin' + if (slug === 'get-user') return lib === 'dart' ? 'auth-currentuser' : 'auth-getuser' + if (slug.startsWith('storage-from-')) return `file-buckets-${slug.slice('storage-from-'.length)}` + if (slug.startsWith('storage-')) return `file-buckets-${slug.slice('storage-'.length)}` + return undefined +} + function htmlShell( lib: string, version: string | null, @@ -74,6 +98,7 @@ function htmlShell( body: string ) { const libraryName = REFERENCES[lib].name + const versionPath = version && version !== REFERENCES[lib].versions[0] ? '/' + version : '' let title = libraryName + ': ' + (section.title ?? '') return ( @@ -84,6 +109,7 @@ function htmlShell( `` + `` + `` + '' + diff --git a/apps/docs/content/guides/auth/auth-mfa/totp.mdx b/apps/docs/content/guides/auth/auth-mfa/totp.mdx index 53cf98f68b5..91b295f840c 100644 --- a/apps/docs/content/guides/auth/auth-mfa/totp.mdx +++ b/apps/docs/content/guides/auth/auth-mfa/totp.mdx @@ -38,7 +38,7 @@ In the **sign-in flow**, the user signs in (upgrading the session to AAL1) and t -[TOTP MFA API](/docs/reference/javascript/auth-mfa-api) is free to use and is enabled on all Supabase projects by default. +[TOTP MFA API](/docs/reference/javascript/auth-mfa) is free to use and is enabled on all Supabase projects by default. diff --git a/apps/docs/content/guides/auth/oauth-server/getting-started.mdx b/apps/docs/content/guides/auth/oauth-server/getting-started.mdx index 94c67088a55..5e46da99e71 100644 --- a/apps/docs/content/guides/auth/oauth-server/getting-started.mdx +++ b/apps/docs/content/guides/auth/oauth-server/getting-started.mdx @@ -637,7 +637,7 @@ Response: -For complete API documentation, see the [OAuth Admin API reference](/docs/reference/javascript/auth-admin-oauth-admin). +For complete API documentation, see the [OAuth Admin API reference](/docs/reference/javascript/oauth-admin). diff --git a/apps/docs/content/guides/auth/oauth-server/oauth-flows.mdx b/apps/docs/content/guides/auth/oauth-server/oauth-flows.mdx index f67a2951508..1d0458f9820 100644 --- a/apps/docs/content/guides/auth/oauth-server/oauth-flows.mdx +++ b/apps/docs/content/guides/auth/oauth-server/oauth-flows.mdx @@ -849,7 +849,7 @@ It's a good practice to provide a settings page where users can view all authori -For complete API reference, see the [OAuth methods in supabase-js](/docs/reference/javascript/auth-admin-oauth-server). +For complete API reference, see the [OAuth methods in supabase-js](/docs/reference/javascript/oauth-server). ## Next steps diff --git a/apps/docs/content/guides/auth/password-security.mdx b/apps/docs/content/guides/auth/password-security.mdx index 428aaeb26f1..6d9b755fc0e 100644 --- a/apps/docs/content/guides/auth/password-security.mdx +++ b/apps/docs/content/guides/auth/password-security.mdx @@ -36,7 +36,7 @@ Leaked password protection is available on the Pro Plan and above. Users will need to be recently logged in to change their password without requiring reauthentication. (A user is considered recently logged in if the session was created within the last 24 hours.) If disabled, a user can change their password at any time. -When enabled, a `nonce` will be sent to the user and this nonce must be validated before the a password change can occur. This can be triggered with the [reauthenticate()](/docs/reference/javascript/auth-reauthentication) API call. +When enabled, a `nonce` will be sent to the user and this nonce must be validated before the a password change can occur. This can be triggered with the [reauthenticate()](/docs/reference/javascript/auth-reauthenticate) API call. ``` const { error } = await supabase.auth.reauthenticate() diff --git a/apps/docs/content/guides/auth/signing-keys.mdx b/apps/docs/content/guides/auth/signing-keys.mdx index 5c36fb584ad..040166c27a2 100644 --- a/apps/docs/content/guides/auth/signing-keys.mdx +++ b/apps/docs/content/guides/auth/signing-keys.mdx @@ -14,7 +14,7 @@ When a JWT is issued by Supabase Auth, the key used to create its [signature](ht | System | Type | Description | | ----------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Legacy | JWT secret | Initially Supabase was designed to use a single shared secret key to sign all JWTs. This includes the `anon` and `service_role` keys, all user access tokens including some [Storage pre-signed URLs](/docs/reference/javascript/storage-from-createsignedurl). **No longer recommended.** Available for backward compatibility. | +| Legacy | JWT secret | Initially Supabase was designed to use a single shared secret key to sign all JWTs. This includes the `anon` and `service_role` keys, all user access tokens including some [Storage pre-signed URLs](/docs/reference/javascript/file-buckets-createsignedurl). **No longer recommended.** Available for backward compatibility. | | Signing keys | Asymmetric key (RSA, Elliptic Curves) | A JWT signing key based on [public-key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography) (RSA, Elliptic Curves) that follows industry best practices and significantly improves the security, reliability and performance of your applications. | | Signing keys | Shared secret key | A JWT signing key based on a [shared secret](https://en.wikipedia.org/wiki/HMAC). | diff --git a/apps/docs/content/guides/security/product-security.mdx b/apps/docs/content/guides/security/product-security.mdx index d1e8ef21589..664d5c5ebe5 100644 --- a/apps/docs/content/guides/security/product-security.mdx +++ b/apps/docs/content/guides/security/product-security.mdx @@ -30,7 +30,7 @@ Various products at Supabase have their own hardening and configuration guides, - [Object ownership](/docs/guides/storage/security/ownership) - [Access control](/docs/guides/storage/security/access-control) - - The Storage API docs contain hints about required [RLS policy permissions](/docs/reference/javascript/storage-createbucket) + - The Storage API docs contain hints about required [RLS policy permissions](/docs/reference/javascript/file-buckets-createbucket) - [Custom roles with the storage schema](/docs/guides/storage/schema/custom-roles) ## Realtime diff --git a/apps/docs/content/guides/self-hosting/self-hosted-custom-oauth-providers.mdx b/apps/docs/content/guides/self-hosting/self-hosted-custom-oauth-providers.mdx index 2fe23d6be8e..f198c22c8ea 100644 --- a/apps/docs/content/guides/self-hosting/self-hosted-custom-oauth-providers.mdx +++ b/apps/docs/content/guides/self-hosting/self-hosted-custom-oauth-providers.mdx @@ -69,7 +69,7 @@ Use the Auth admin API to create providers. You need your project's secret key f -The JavaScript examples use a [supabase-js](/docs/reference/javascript/start) client created with the secret key (`SUPABASE_SECRET_KEY`), which must only run in trusted server-side environments. +The JavaScript examples use a [supabase-js](/docs/reference/javascript/introduction) client created with the secret key (`SUPABASE_SECRET_KEY`), which must only run in trusted server-side environments. diff --git a/apps/docs/content/guides/storage/buckets/creating-buckets.mdx b/apps/docs/content/guides/storage/buckets/creating-buckets.mdx index ea2623bbeff..2763b2ac01d 100644 --- a/apps/docs/content/guides/storage/buckets/creating-buckets.mdx +++ b/apps/docs/content/guides/storage/buckets/creating-buckets.mdx @@ -29,7 +29,7 @@ const { data, error } = await supabase.storage.createBucket('avatars', { }) ``` -[Reference.](/docs/reference/javascript/storage-createbucket) +[Reference.](/docs/reference/javascript/file-buckets-createbucket) diff --git a/apps/docs/content/guides/storage/buckets/fundamentals.mdx b/apps/docs/content/guides/storage/buckets/fundamentals.mdx index 1a1ff75fb24..190e678d6c4 100644 --- a/apps/docs/content/guides/storage/buckets/fundamentals.mdx +++ b/apps/docs/content/guides/storage/buckets/fundamentals.mdx @@ -17,8 +17,8 @@ When a bucket is set to **Private** all operations are subject to access control The only ways to download assets within a private bucket is to: -- Use the [download method](/docs/reference/javascript/storage-from-download) by providing an authorization header containing your user's JWT. The RLS policy you create on the `storage.objects` table will use this user to determine if they have access. -- Create a signed URL with the [`createSignedUrl` method](/docs/reference/javascript/storage-from-createsignedurl) that can be accessed for a limited time. +- Use the [download method](/docs/reference/javascript/file-buckets-download) by providing an authorization header containing your user's JWT. The RLS policy you create on the `storage.objects` table will use this user to determine if they have access. +- Create a signed URL with the [`createSignedUrl` method](/docs/reference/javascript/file-buckets-createsignedurl) that can be accessed for a limited time. #### Example use cases: diff --git a/apps/docs/content/guides/storage/cdn/smart-cdn.mdx b/apps/docs/content/guides/storage/cdn/smart-cdn.mdx index 802b481d9e7..a1297055cf3 100644 --- a/apps/docs/content/guides/storage/cdn/smart-cdn.mdx +++ b/apps/docs/content/guides/storage/cdn/smart-cdn.mdx @@ -17,7 +17,7 @@ Smart CDN caching is automatically enabled for [Pro Plan and above](/pricing). ## Cache duration -When Smart CDN is enabled, the asset is cached on the CDN for as long as possible. You can still control how long assets are stored in the browser using the [`cacheControl`](/docs/reference/javascript/storage-from-upload) option when uploading a file. Smart CDN caching works with all types of storage operations including signed URLs. +When Smart CDN is enabled, the asset is cached on the CDN for as long as possible. You can still control how long assets are stored in the browser using the [`cacheControl`](/docs/reference/javascript/file-buckets-upload) option when uploading a file. Smart CDN caching works with all types of storage operations including signed URLs. When a file is updated or deleted, the CDN cache is automatically invalidated to reflect the change (including transformed images). It can take **up to 60 seconds** for the CDN cache to be invalidated as the asset metadata has to propagate across all the data-centers around the globe. diff --git a/apps/docs/content/guides/storage/quickstart.mdx b/apps/docs/content/guides/storage/quickstart.mdx index e3a39dc60f0..70e8c5c94e5 100644 --- a/apps/docs/content/guides/storage/quickstart.mdx +++ b/apps/docs/content/guides/storage/quickstart.mdx @@ -69,7 +69,7 @@ values const { data, error } = await supabase.storage.createBucket('avatars') ``` -[Reference.](/docs/reference/javascript/storage-createbucket) +[Reference.](/docs/reference/javascript/file-buckets-createbucket) <$Show if="sdk:dart"> @@ -152,7 +152,7 @@ const { data, error } = await supabase.storage .upload('public/avatar1.png', avatarFile) ``` -[Reference.](/docs/reference/javascript/storage-from-upload) +[Reference.](/docs/reference/javascript/file-buckets-upload) <$Show if="sdk:dart"> @@ -220,7 +220,7 @@ You can download a file from the Dashboard, or within a browser using our JS lib const { data, error } = await supabase.storage.from('avatars').download('public/avatar1.png') ``` -[Reference.](/docs/reference/javascript/storage-from-download) +[Reference.](/docs/reference/javascript/file-buckets-download) <$Show if="sdk:dart"> @@ -237,7 +237,7 @@ void main() async { } ``` -[Reference.](/docs/reference/dart/storage-from-download) +[Reference.](/docs/reference/dart/file-buckets-download) diff --git a/apps/docs/content/guides/storage/security/access-control.mdx b/apps/docs/content/guides/storage/security/access-control.mdx index c3ec9d7c99b..6c704b4040b 100644 --- a/apps/docs/content/guides/storage/security/access-control.mdx +++ b/apps/docs/content/guides/storage/security/access-control.mdx @@ -20,11 +20,11 @@ If you need different `SELECT` policies for different Storage actions, such as l -The RLS policies required for different operations are documented [here](/docs/reference/javascript/storage-createbucket) +The RLS policies required for different operations are documented [here](/docs/reference/javascript/file-buckets-createbucket) -For example, the only RLS policy required for [uploading](/docs/reference/javascript/storage-from-upload) objects is to grant the `INSERT` permission to the `storage.objects` table. +For example, the only RLS policy required for [uploading](/docs/reference/javascript/file-buckets-upload) objects is to grant the `INSERT` permission to the `storage.objects` table. To allow overwriting files using the `upsert` functionality you will need to additionally grant `SELECT` and `UPDATE` permissions. diff --git a/apps/docs/content/guides/storage/serving/downloads.mdx b/apps/docs/content/guides/storage/serving/downloads.mdx index 23235fb6c1f..a87414af5e0 100644 --- a/apps/docs/content/guides/storage/serving/downloads.mdx +++ b/apps/docs/content/guides/storage/serving/downloads.mdx @@ -77,7 +77,7 @@ final response = await supabase.storage ); ``` -[Reference.](/docs/reference/dart/storage-from-download) +[Reference.](/docs/reference/dart/file-buckets-download) diff --git a/apps/docs/docs/ref/javascript/v1/upgrade-guide.mdx b/apps/docs/docs/ref/javascript/v1/upgrade-guide.mdx index 012df19d55e..6bca433e28b 100644 --- a/apps/docs/docs/ref/javascript/v1/upgrade-guide.mdx +++ b/apps/docs/docs/ref/javascript/v1/upgrade-guide.mdx @@ -69,7 +69,7 @@ const supabase = createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, { -Read more about the [constructor options](/docs/reference/javascript/release-notes#explicit-constructor-options). +Read more about the [constructor options](/docs/reference/javascript/initializing). ### Auth methods diff --git a/apps/docs/features/docs/Reference.utils.ts b/apps/docs/features/docs/Reference.utils.ts index 5fe986caaee..b5d752c2c28 100644 --- a/apps/docs/features/docs/Reference.utils.ts +++ b/apps/docs/features/docs/Reference.utils.ts @@ -37,7 +37,7 @@ export function parseReferencePath(slug: Array) { let maybeCrawlers: string | null let path: string[] ;[sdkId, maybeVersion, maybeCrawlers, ...path] = slug - if (!/v\d+/.test(maybeVersion)) { + if (!/^v\d+$/.test(maybeVersion)) { maybeVersion = null path = [maybeCrawlers, ...path] maybeCrawlers = maybeVersion diff --git a/apps/docs/middleware.test.ts b/apps/docs/middleware.test.ts index 87d171621d9..fa230758a30 100644 --- a/apps/docs/middleware.test.ts +++ b/apps/docs/middleware.test.ts @@ -163,3 +163,23 @@ describe('docs middleware — /guides/* content negotiation', () => { expect(rewrite).not.toContain('/api/guides-md/') }) }) + +describe('docs middleware — reference paths', () => { + it('does not mistake listv2 for a version segment', () => { + const path = '/docs/reference/javascript/file-buckets-listv2' + expect( + middleware(makeRequest(path, { userAgent: 'Googlebot' })).headers.get(REWRITE_HEADER) + ).toBe('https://supabase.com/docs/api/crawlers') + expect(middleware(makeRequest(path)).headers.get(REWRITE_HEADER)).toBe( + 'https://supabase.com/docs/reference/javascript' + ) + }) + + it('sends the Kotlin root to the crawler renderer for bots', () => { + expect( + middleware(makeRequest('/docs/reference/kotlin', { userAgent: 'Googlebot' })).headers.get( + REWRITE_HEADER + ) + ).toBe('https://supabase.com/docs/api/crawlers') + }) +}) diff --git a/apps/docs/middleware.ts b/apps/docs/middleware.ts index cd31319d43f..1e7010c391d 100644 --- a/apps/docs/middleware.ts +++ b/apps/docs/middleware.ts @@ -43,7 +43,7 @@ export function middleware(request: NextRequest) { let [, lib, maybeVersion, ...slug] = pathname.replace(REFERENCE_PATH, '').split('/') if (clientSdkIds.includes(lib)) { - const version = /v\d+/.test(maybeVersion) ? maybeVersion : undefined + const version = /^v\d+$/.test(maybeVersion) ? maybeVersion : undefined if (!version) { slug = [maybeVersion, ...slug] } @@ -77,7 +77,7 @@ export function middleware(request: NextRequest) { } if (clientSdkIds.includes(lib)) { - const version = /v\d+/.test(maybeVersion) ? maybeVersion : null + const version = /^v\d+$/.test(maybeVersion) ? maybeVersion : null const rewritePath = [REFERENCE_PATH, lib, version].filter(Boolean).join('/') return NextResponse.rewrite(new URL(rewritePath, request.url)) } diff --git a/apps/docs/spec/supabase_dart_v1.yml b/apps/docs/spec/supabase_dart_v1.yml index 2df29e61371..4e10f496377 100644 --- a/apps/docs/spec/supabase_dart_v1.yml +++ b/apps/docs/spec/supabase_dart_v1.yml @@ -1553,7 +1553,7 @@ functions: Retrieve URLs for assets in public buckets title: 'from.getPublicUrl()' notes: | - - The bucket needs to be set to public, either via [updateBucket()](/docs/reference/dart/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public" + - The bucket needs to be set to public, either via [updateBucket()](/docs/reference/dart/v1/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public" - Policy permissions required: - `buckets` permissions: none - `objects` permissions: none diff --git a/apps/docs/spec/supabase_dart_v2.yml b/apps/docs/spec/supabase_dart_v2.yml index 8fba01c8673..56dfefcafcf 100644 --- a/apps/docs/spec/supabase_dart_v2.yml +++ b/apps/docs/spec/supabase_dart_v2.yml @@ -948,7 +948,7 @@ functions: - Drives the full WebAuthn ceremony end to end: starts the challenge with the Supabase server, calls the `authenticator` you supply to prompt the user for biometrics or a security key, and verifies the credential with the server. - Does not require an existing session. On success the session is persisted and an `AuthChangeEvent.signedIn` event is fired. - `supabase_flutter` does not depend on a passkey plugin directly. Pass an implementation of `PasskeyAuthenticatorInterface`, such as the [`passkeys`](https://pub.dev/packages/passkeys) plugin's `PasskeyAuthenticator` (since `passkeys` `2.21.0`). - - For native flows or custom UI, use the lower-level [`auth.passkey`](/docs/reference/dart/auth-passkey-api) namespace instead. + - For native flows or custom UI, use the lower-level [`auth.passkey`](/docs/reference/dart/auth-passkey) namespace instead. - Passkeys are a BETA feature and must be enabled for your project in the Supabase Dashboard under Authentication > Configuration > Passkeys. - Platform setup the library cannot perform (Associated Domains on iOS/macOS, Digital Asset Links on Android, the `passkeys` web SDK on web) is documented in the `supabase_flutter` package README. params: @@ -982,7 +982,7 @@ functions: - Drives the full WebAuthn ceremony end to end: starts the registration with the Supabase server, calls the `authenticator` you supply to create a credential on the device, and verifies it with the server. - Requires a signed in (non-anonymous) user. If the user has verified MFA factors, the session has to be at `aal2` to manage passkeys. - `supabase_flutter` does not depend on a passkey plugin directly. Pass an implementation of `PasskeyAuthenticatorInterface`, such as the [`passkeys`](https://pub.dev/packages/passkeys) plugin's `PasskeyAuthenticator` (since `passkeys` `2.21.0`). - - For native flows or custom UI, use the lower-level [`auth.passkey`](/docs/reference/dart/auth-passkey-api) namespace instead. + - For native flows or custom UI, use the lower-level [`auth.passkey`](/docs/reference/dart/auth-passkey) namespace instead. - Passkeys are a BETA feature and must be enabled for your project in the Supabase Dashboard under Authentication > Configuration > Passkeys. params: - name: authenticator @@ -2379,7 +2379,7 @@ functions: - id: passkey-verify-registration title: 'passkey.verifyRegistration()' notes: | - Completes the registration of a new passkey and returns the stored [`Passkey`](/docs/reference/dart/auth-passkey-api). + Completes the registration of a new passkey and returns the stored [`Passkey`](/docs/reference/dart/auth-passkey). params: - name: challengeId isOptional: false @@ -5329,7 +5329,7 @@ functions: Retrieve URLs for assets in public buckets title: 'from.getPublicUrl()' notes: | - - The bucket needs to be set to public, either via [updateBucket()](/docs/reference/dart/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public" + - The bucket needs to be set to public, either via [updateBucket()](/docs/reference/dart/file-buckets-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public" - Policy permissions required: - `buckets` permissions: none - `objects` permissions: none @@ -5537,7 +5537,7 @@ functions: title: 'from.downloadStream()' notes: | - The request is sent when the stream is listened to. A non-success response surfaces as a `StorageException` on the stream before any bytes are emitted. - - Prefer this over [`download()`](/docs/reference/dart/storage-from-download) for large files to keep memory usage low. + - Prefer this over [`download()`](/docs/reference/dart/file-buckets-download) for large files to keep memory usage low. - Policy permissions required: - `buckets` permissions: none - `objects` permissions: `select` diff --git a/apps/docs/spec/supabase_js_v1.yml b/apps/docs/spec/supabase_js_v1.yml index d11dc4343e6..6b4bf237263 100644 --- a/apps/docs/spec/supabase_js_v1.yml +++ b/apps/docs/spec/supabase_js_v1.yml @@ -1532,7 +1532,7 @@ functions: title: 'from.getPublicUrl()' $ref: '@supabase/storage-js."lib/StorageFileApi".StorageFileApi.getPublicUrl' notes: | - - The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public" + - The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/v1/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public" - Policy permissions required: - `buckets` permissions: none - `objects` permissions: none diff --git a/apps/docs/spec/supabase_swift_v1.yml b/apps/docs/spec/supabase_swift_v1.yml index e7c455a60ee..ff35448cb03 100644 --- a/apps/docs/spec/supabase_swift_v1.yml +++ b/apps/docs/spec/supabase_swift_v1.yml @@ -3333,7 +3333,7 @@ functions: - id: from-get-public-url title: from.getPublicUrl() notes: | - - The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public" + - The bucket needs to be set to public, either via [updateBucket()](/docs/reference/swift/v1/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public" - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: none diff --git a/apps/docs/spec/supabase_swift_v2.yml b/apps/docs/spec/supabase_swift_v2.yml index 71a11780711..a3673f90b56 100644 --- a/apps/docs/spec/supabase_swift_v2.yml +++ b/apps/docs/spec/supabase_swift_v2.yml @@ -5691,7 +5691,7 @@ functions: - id: from-get-public-url title: from.getPublicUrl() notes: | - - The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public" + - The bucket needs to be set to public, either via [updateBucket()](/docs/reference/swift/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public" - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: none