Init
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
||||
# Agent instructions for `@supabase/supabase-js`
|
||||
|
||||
Main isomorphic Supabase client for JavaScript. Aggregates `@supabase/auth-js`, `@supabase/postgrest-js`, `@supabase/realtime-js`, `@supabase/storage-js`, and `@supabase/functions-js` into one client.
|
||||
|
||||
When helping a user work with this package:
|
||||
|
||||
- **Usage and quick start**: [`README.md`](./README.md)
|
||||
- **Full API reference**: [`src/`](./src/) — every public method and type has TSDoc with `@example` blocks. Read the source for the canonical, version-pinned answer.
|
||||
- **Migration notes**: [`migrations/`](./migrations/) — per-theme markdown files for changes that need caller action.
|
||||
|
||||
For broader Supabase guidance (docs site, MCP tools, schema and project workflows), use the centralized [Supabase agent skills](https://github.com/supabase/agent-skills): `npx skills add supabase/agent-skills`. Or pair with the Supabase MCP server via the [Supabase Plugin for AI Coding Agents](https://supabase.com/docs/guides/getting-started/plugins).
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Supabase
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+290
@@ -0,0 +1,290 @@
|
||||
<br />
|
||||
<p align="center">
|
||||
<a href="https://supabase.io">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--dark.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--light.svg">
|
||||
<img alt="Supabase Logo" width="300" src="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/logo-preview.jpg">
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
<h1 align="center">Supabase JS SDK</h1>
|
||||
|
||||
<h3 align="center">Isomorphic JavaScript SDK for Supabase - combining Auth, Database, Storage, Functions, and Realtime.</h3>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://supabase.com/docs/guides/getting-started">Guides</a>
|
||||
·
|
||||
<a href="https://supabase.com/docs/reference/javascript/start">Reference Docs</a>
|
||||
·
|
||||
<a href="https://supabase.github.io/supabase-js/supabase-js/v2/spec.json">TypeDoc</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://github.com/supabase/supabase-js/actions?query=branch%3Amaster)
|
||||
[](https://www.npmjs.com/package/@supabase/supabase-js)
|
||||
[](#license)
|
||||
[](https://pkg.pr.new/~/supabase/supabase-js)
|
||||
|
||||
</div>
|
||||
|
||||
## Usage
|
||||
|
||||
First of all, you need to install the library:
|
||||
|
||||
```sh
|
||||
npm install @supabase/supabase-js
|
||||
```
|
||||
|
||||
Then you're able to import the library and establish the connection with the database:
|
||||
|
||||
```js
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
|
||||
// Create a single supabase client for interacting with your database
|
||||
const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
```
|
||||
|
||||
### UMD
|
||||
|
||||
You can use plain `<script>`s to import supabase-js from CDNs, like:
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
|
||||
```
|
||||
|
||||
or even:
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/@supabase/supabase-js@2"></script>
|
||||
```
|
||||
|
||||
Then you can use it from a global `supabase` variable:
|
||||
|
||||
```html
|
||||
<script>
|
||||
const { createClient } = supabase
|
||||
const _supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
|
||||
console.log('Supabase Instance: ', _supabase)
|
||||
// ...
|
||||
</script>
|
||||
```
|
||||
|
||||
### ESM
|
||||
|
||||
You can use `<script type="module">` to import supabase-js from CDNs, like:
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { createClient } from 'https://cdn.jsdelivr.net/npm/@supabase/supabase-js/+esm'
|
||||
const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
|
||||
console.log('Supabase Instance: ', supabase)
|
||||
// ...
|
||||
</script>
|
||||
```
|
||||
|
||||
### Deno
|
||||
|
||||
You can use supabase-js in the Deno runtime via [JSR](https://jsr.io/@supabase/supabase-js):
|
||||
|
||||
```js
|
||||
import { createClient } from 'jsr:@supabase/supabase-js@2'
|
||||
```
|
||||
|
||||
### Custom `fetch` implementation
|
||||
|
||||
`supabase-js` uses the runtime's global `fetch` to make HTTP requests, but an alternative `fetch` implementation can be provided as an option. This is useful in environments where the global `fetch` is unavailable or where you want to customize request behavior:
|
||||
|
||||
```js
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
|
||||
// Provide a custom `fetch` implementation as an option
|
||||
const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
global: {
|
||||
fetch: (...args) => fetch(...args),
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Distributed Tracing with OpenTelemetry
|
||||
|
||||
The Supabase JS SDK can attach W3C/OpenTelemetry trace context headers (`traceparent`, `tracestate`, `baggage`) to outgoing requests, enabling end-to-end request tracing from your client application through Supabase services.
|
||||
|
||||
Trace propagation is **opt-in** and disabled by default. When enabled, headers are only attached to requests targeting Supabase domains (`*.supabase.co`, `*.supabase.in`, `localhost`).
|
||||
|
||||
#### Enable trace propagation
|
||||
|
||||
```js
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
import { trace } from '@opentelemetry/api'
|
||||
|
||||
const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key', {
|
||||
tracePropagation: true,
|
||||
})
|
||||
|
||||
const tracer = trace.getTracer('my-app')
|
||||
await tracer.startActiveSpan('fetch-users', async (span) => {
|
||||
// This request now includes the active trace context.
|
||||
const { data, error } = await supabase.from('users').select('*')
|
||||
span.end()
|
||||
})
|
||||
```
|
||||
|
||||
If `@opentelemetry/api` is not installed or no active context exists, the SDK silently no-ops.
|
||||
|
||||
#### Advanced configuration
|
||||
|
||||
```typescript
|
||||
interface TracePropagationOptions {
|
||||
// Enable trace propagation (default: false).
|
||||
enabled?: boolean
|
||||
|
||||
// Respect upstream sampling decisions (default: true).
|
||||
// When true, headers are skipped if the upstream trace is not sampled.
|
||||
respectSamplingDecision?: boolean
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
// Always propagate, even for non-sampled traces.
|
||||
const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key', {
|
||||
tracePropagation: { enabled: true, respectSamplingDecision: false },
|
||||
})
|
||||
```
|
||||
|
||||
## Support Policy
|
||||
|
||||
This section outlines the scope of support for various runtime environments in Supabase JavaScript client.
|
||||
|
||||
### Node.js
|
||||
|
||||
We only support Node.js versions that are in **Active LTS** or **Maintenance** status as defined by the [official Node.js release schedule](https://nodejs.org/en/about/previous-releases#release-schedule). This means we support versions that are currently receiving long-term support and critical bug fixes.
|
||||
|
||||
When a Node.js version reaches end-of-life and is no longer in Active LTS or Maintenance status, Supabase will drop it in a **minor release**, and **this won't be considered a breaking change**.
|
||||
|
||||
> ⚠️ **Node.js 18 Deprecation Notice**
|
||||
>
|
||||
> Node.js 18 reached end-of-life on April 30, 2025. As announced in [our deprecation notice](https://github.com/orgs/supabase/discussions/37217), support for Node.js 18 was dropped in version `2.79.0`.
|
||||
>
|
||||
> If you must use Node.js 18, please use version `2.78.0`, which is the last version that supported Node.js 18.
|
||||
|
||||
> ⚠️ **Node.js 20 Deprecation Notice**
|
||||
>
|
||||
> Node.js 20 reached end-of-life on April 30, 2026. As announced in [our deprecation notice](https://github.com/orgs/supabase/discussions/45715), support for Node.js 20 was dropped in version `2.110.0`.
|
||||
>
|
||||
> If you must use Node.js 20, please use version `2.109.0`, which is the last version that supported Node.js 20.
|
||||
|
||||
### Deno
|
||||
|
||||
We support Deno versions that are currently receiving active development and security updates. We follow the [official Deno release schedule](https://docs.deno.com/runtime/fundamentals/stability_and_releases/) and only support versions from the `stable` and `lts` release channels.
|
||||
|
||||
When a Deno version reaches end-of-life and is no longer receiving security updates, Supabase will drop it in a **minor release**, and **this won't be considered a breaking change**.
|
||||
|
||||
### Browsers
|
||||
|
||||
All modern browsers are supported. We support browsers that provide native `fetch` API. For Realtime features, browsers must also support native `WebSocket` API.
|
||||
|
||||
### Bun
|
||||
|
||||
We support Bun runtime environments. Bun provides native fetch support and is compatible with Node.js APIs. Since Bun does not follow a structured release schedule like Node.js or Deno, we support current stable versions of Bun and may drop support for older versions in minor releases without considering it a breaking change.
|
||||
|
||||
### React Native
|
||||
|
||||
We support React Native environments with fetch polyfills provided by the framework. Since React Native does not follow a structured release schedule, we support current stable versions and may drop support for older versions in minor releases without considering it a breaking change.
|
||||
|
||||
### Cloudflare Workers
|
||||
|
||||
We support Cloudflare Workers runtime environments. Cloudflare Workers provides native fetch support. Since Cloudflare Workers does not follow a structured release schedule, we support current stable versions and may drop support for older versions in minor releases without considering it a breaking change.
|
||||
|
||||
### Important Notes
|
||||
|
||||
- **Experimental features**: Features marked as experimental may be removed or changed without notice
|
||||
|
||||
## Known Build Warnings
|
||||
|
||||
### `UNUSED_EXTERNAL_IMPORT` in Vite / Rollup / Nuxt
|
||||
|
||||
When bundling your app, you may see warnings like:
|
||||
|
||||
```
|
||||
"PostgrestError" is imported from external module "@supabase/postgrest-js" but never used in "...supabase-js/dist/index.mjs".
|
||||
"FunctionRegion", "FunctionsError", "FunctionsFetchError", "FunctionsHttpError" and "FunctionsRelayError" are imported from external module "@supabase/functions-js" but never used in "...".
|
||||
```
|
||||
|
||||
**This is a false positive — your bundle is fine.** Here is why it happens:
|
||||
|
||||
`@supabase/supabase-js` re-exports `PostgrestError`, `FunctionsError`, and related symbols so you can import them directly from `@supabase/supabase-js`. However, our build tool merges all imports from the same package into a single import statement in the built output:
|
||||
|
||||
```js
|
||||
// dist/index.mjs (simplified)
|
||||
import { PostgrestClient, PostgrestError } from '@supabase/postgrest-js'
|
||||
// ^ used internally ^ re-exported for you
|
||||
```
|
||||
|
||||
Your bundler checks which names from that import are used _in the code body_, and flags `PostgrestError` as unused because it only appears in an `export` statement — not called or assigned. The export itself is the usage, but downstream bundlers don't track this correctly. This is a known Rollup/Vite limitation with re-exported external imports.
|
||||
|
||||
**Nothing is broken.** Tree-shaking and bundle size are unaffected.
|
||||
|
||||
To suppress the warning:
|
||||
|
||||
**Vite / Rollup (`vite.config.js` or `rollup.config.js`):**
|
||||
|
||||
```js
|
||||
export default {
|
||||
build: {
|
||||
rollupOptions: {
|
||||
onwarn(warning, warn) {
|
||||
if (warning.code === 'UNUSED_EXTERNAL_IMPORT' && warning.exporter?.includes('@supabase/'))
|
||||
return
|
||||
warn(warning)
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
**Nuxt (`nuxt.config.ts`):**
|
||||
|
||||
```ts
|
||||
export default defineNuxtConfig({
|
||||
vite: {
|
||||
build: {
|
||||
rollupOptions: {
|
||||
onwarn(warning, warn) {
|
||||
if (warning.code === 'UNUSED_EXTERNAL_IMPORT' && warning.exporter?.includes('@supabase/'))
|
||||
return
|
||||
warn(warning)
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions! Please see our [Contributing Guide](../../../CONTRIBUTING.md) for details on how to get started.
|
||||
|
||||
For major changes or if you're unsure about something, please open an issue first to discuss your proposed changes.
|
||||
|
||||
### Building
|
||||
|
||||
```bash
|
||||
# From the monorepo root
|
||||
pnpm nx build supabase-js
|
||||
|
||||
# Or with watch mode for development
|
||||
pnpm nx build supabase-js --watch
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
There's a complete guide on how to set up your environment for running locally the `supabase-js` integration tests. Please refer to [TESTING.md](./TESTING.md).
|
||||
|
||||
## Badges
|
||||
|
||||
[](https://coveralls.io/github/supabase/supabase-js?branch=master)
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
const require_index = require('./index.cjs');
|
||||
|
||||
//#region src/cors.ts
|
||||
/**
|
||||
* Canonical CORS configuration for Supabase Edge Functions
|
||||
*
|
||||
* This module exports CORS headers that stay synchronized with the Supabase SDK.
|
||||
* When new headers are added to the SDK, they are automatically included here,
|
||||
* preventing CORS errors in Edge Functions.
|
||||
*
|
||||
* @example Basic usage
|
||||
* ```typescript
|
||||
* import { corsHeaders } from '@supabase/supabase-js/cors'
|
||||
*
|
||||
* Deno.serve(async (req) => {
|
||||
* if (req.method === 'OPTIONS') {
|
||||
* return new Response('ok', { headers: corsHeaders })
|
||||
* }
|
||||
*
|
||||
* return new Response(
|
||||
* JSON.stringify({ data: 'Hello' }),
|
||||
* { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
* )
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @module cors
|
||||
*/
|
||||
/**
|
||||
* All custom headers sent by the Supabase SDK.
|
||||
* These headers need to be included in CORS configuration to prevent preflight failures.
|
||||
*
|
||||
* Headers:
|
||||
* - authorization: Bearer token for authentication
|
||||
* - x-client-info: Library version information
|
||||
* - apikey: Project API key
|
||||
* - content-type: Standard HTTP content type
|
||||
* - x-retry-count: Retry attempt number sent by postgrest-js on retried requests
|
||||
*/
|
||||
const SUPABASE_HEADERS = [
|
||||
"authorization",
|
||||
"x-client-info",
|
||||
"apikey",
|
||||
"content-type",
|
||||
"x-retry-count"
|
||||
].join(", ");
|
||||
/**
|
||||
* All HTTP methods used by the Supabase SDK
|
||||
*/
|
||||
const SUPABASE_METHODS = [
|
||||
"GET",
|
||||
"POST",
|
||||
"PUT",
|
||||
"PATCH",
|
||||
"DELETE",
|
||||
"OPTIONS"
|
||||
].join(", ");
|
||||
/**
|
||||
* Default CORS headers for Supabase Edge Functions.
|
||||
*
|
||||
* Includes all headers sent by Supabase client libraries and allows all standard HTTP methods.
|
||||
* Use this for simple CORS configurations with wildcard origin.
|
||||
*
|
||||
* @example Basic usage
|
||||
* ```typescript
|
||||
* import { corsHeaders } from '@supabase/supabase-js/cors'
|
||||
*
|
||||
* Deno.serve(async (req) => {
|
||||
* if (req.method === 'OPTIONS') {
|
||||
* return new Response('ok', { headers: corsHeaders })
|
||||
* }
|
||||
*
|
||||
* return new Response(
|
||||
* JSON.stringify({ data: 'Hello' }),
|
||||
* { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
* )
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @category Edge Functions
|
||||
*/
|
||||
const corsHeaders = {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Headers": SUPABASE_HEADERS,
|
||||
"Access-Control-Allow-Methods": SUPABASE_METHODS
|
||||
};
|
||||
|
||||
//#endregion
|
||||
exports.corsHeaders = corsHeaders;
|
||||
//# sourceMappingURL=cors.cjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cors.cjs","names":["corsHeaders: CorsHeaders"],"sources":["../src/cors.ts"],"sourcesContent":["/**\n * Canonical CORS configuration for Supabase Edge Functions\n *\n * This module exports CORS headers that stay synchronized with the Supabase SDK.\n * When new headers are added to the SDK, they are automatically included here,\n * preventing CORS errors in Edge Functions.\n *\n * @example Basic usage\n * ```typescript\n * import { corsHeaders } from '@supabase/supabase-js/cors'\n *\n * Deno.serve(async (req) => {\n * if (req.method === 'OPTIONS') {\n * return new Response('ok', { headers: corsHeaders })\n * }\n *\n * return new Response(\n * JSON.stringify({ data: 'Hello' }),\n * { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n * )\n * })\n * ```\n *\n * @module cors\n */\n\n/**\n * All custom headers sent by the Supabase SDK.\n * These headers need to be included in CORS configuration to prevent preflight failures.\n *\n * Headers:\n * - authorization: Bearer token for authentication\n * - x-client-info: Library version information\n * - apikey: Project API key\n * - content-type: Standard HTTP content type\n * - x-retry-count: Retry attempt number sent by postgrest-js on retried requests\n */\nconst SUPABASE_HEADERS = [\n 'authorization',\n 'x-client-info',\n 'apikey',\n 'content-type',\n 'x-retry-count',\n].join(', ')\n\n/**\n * All HTTP methods used by the Supabase SDK\n */\nconst SUPABASE_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'].join(', ')\n\n/**\n * Type representing CORS headers as a record of header names to values\n */\nexport type CorsHeaders = Record<string, string>\n\n/**\n * Default CORS headers for Supabase Edge Functions.\n *\n * Includes all headers sent by Supabase client libraries and allows all standard HTTP methods.\n * Use this for simple CORS configurations with wildcard origin.\n *\n * @example Basic usage\n * ```typescript\n * import { corsHeaders } from '@supabase/supabase-js/cors'\n *\n * Deno.serve(async (req) => {\n * if (req.method === 'OPTIONS') {\n * return new Response('ok', { headers: corsHeaders })\n * }\n *\n * return new Response(\n * JSON.stringify({ data: 'Hello' }),\n * { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n * )\n * })\n * ```\n *\n * @category Edge Functions\n */\nexport const corsHeaders: CorsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': SUPABASE_HEADERS,\n 'Access-Control-Allow-Methods': SUPABASE_METHODS,\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,MAAM,mBAAmB;CACvB;CACA;CACA;CACA;CACA;CACD,CAAC,KAAK,KAAK;;;;AAKZ,MAAM,mBAAmB;CAAC;CAAO;CAAQ;CAAO;CAAS;CAAU;CAAU,CAAC,KAAK,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;AA+BxF,MAAaA,cAA2B;CACtC,+BAA+B;CAC/B,gCAAgC;CAChC,gCAAgC;CACjC"}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
//#region src/cors.d.ts
|
||||
/**
|
||||
* Canonical CORS configuration for Supabase Edge Functions
|
||||
*
|
||||
* This module exports CORS headers that stay synchronized with the Supabase SDK.
|
||||
* When new headers are added to the SDK, they are automatically included here,
|
||||
* preventing CORS errors in Edge Functions.
|
||||
*
|
||||
* @example Basic usage
|
||||
* ```typescript
|
||||
* import { corsHeaders } from '@supabase/supabase-js/cors'
|
||||
*
|
||||
* Deno.serve(async (req) => {
|
||||
* if (req.method === 'OPTIONS') {
|
||||
* return new Response('ok', { headers: corsHeaders })
|
||||
* }
|
||||
*
|
||||
* return new Response(
|
||||
* JSON.stringify({ data: 'Hello' }),
|
||||
* { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
* )
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @module cors
|
||||
*/
|
||||
/**
|
||||
* Type representing CORS headers as a record of header names to values
|
||||
*/
|
||||
type CorsHeaders = Record<string, string>;
|
||||
/**
|
||||
* Default CORS headers for Supabase Edge Functions.
|
||||
*
|
||||
* Includes all headers sent by Supabase client libraries and allows all standard HTTP methods.
|
||||
* Use this for simple CORS configurations with wildcard origin.
|
||||
*
|
||||
* @example Basic usage
|
||||
* ```typescript
|
||||
* import { corsHeaders } from '@supabase/supabase-js/cors'
|
||||
*
|
||||
* Deno.serve(async (req) => {
|
||||
* if (req.method === 'OPTIONS') {
|
||||
* return new Response('ok', { headers: corsHeaders })
|
||||
* }
|
||||
*
|
||||
* return new Response(
|
||||
* JSON.stringify({ data: 'Hello' }),
|
||||
* { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
* )
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @category Edge Functions
|
||||
*/
|
||||
declare const corsHeaders: CorsHeaders;
|
||||
//#endregion
|
||||
export { CorsHeaders, corsHeaders };
|
||||
//# sourceMappingURL=cors.d.cts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cors.d.cts","names":[],"sources":["../src/cors.ts"],"sourcesContent":[],"mappings":";;AAqDA;AA0BA;;;;;;;;;;;;;;;;;;;;;;;;;;KA1BY,WAAA,GAAc;;;;;;;;;;;;;;;;;;;;;;;;;cA0Bb,aAAa"}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
//#region src/cors.d.ts
|
||||
/**
|
||||
* Canonical CORS configuration for Supabase Edge Functions
|
||||
*
|
||||
* This module exports CORS headers that stay synchronized with the Supabase SDK.
|
||||
* When new headers are added to the SDK, they are automatically included here,
|
||||
* preventing CORS errors in Edge Functions.
|
||||
*
|
||||
* @example Basic usage
|
||||
* ```typescript
|
||||
* import { corsHeaders } from '@supabase/supabase-js/cors'
|
||||
*
|
||||
* Deno.serve(async (req) => {
|
||||
* if (req.method === 'OPTIONS') {
|
||||
* return new Response('ok', { headers: corsHeaders })
|
||||
* }
|
||||
*
|
||||
* return new Response(
|
||||
* JSON.stringify({ data: 'Hello' }),
|
||||
* { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
* )
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @module cors
|
||||
*/
|
||||
/**
|
||||
* Type representing CORS headers as a record of header names to values
|
||||
*/
|
||||
type CorsHeaders = Record<string, string>;
|
||||
/**
|
||||
* Default CORS headers for Supabase Edge Functions.
|
||||
*
|
||||
* Includes all headers sent by Supabase client libraries and allows all standard HTTP methods.
|
||||
* Use this for simple CORS configurations with wildcard origin.
|
||||
*
|
||||
* @example Basic usage
|
||||
* ```typescript
|
||||
* import { corsHeaders } from '@supabase/supabase-js/cors'
|
||||
*
|
||||
* Deno.serve(async (req) => {
|
||||
* if (req.method === 'OPTIONS') {
|
||||
* return new Response('ok', { headers: corsHeaders })
|
||||
* }
|
||||
*
|
||||
* return new Response(
|
||||
* JSON.stringify({ data: 'Hello' }),
|
||||
* { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
* )
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @category Edge Functions
|
||||
*/
|
||||
declare const corsHeaders: CorsHeaders;
|
||||
//#endregion
|
||||
export { CorsHeaders, corsHeaders };
|
||||
//# sourceMappingURL=cors.d.mts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cors.d.mts","names":[],"sources":["../src/cors.ts"],"sourcesContent":[],"mappings":";;AAqDA;AA0BA;;;;;;;;;;;;;;;;;;;;;;;;;;KA1BY,WAAA,GAAc;;;;;;;;;;;;;;;;;;;;;;;;;cA0Bb,aAAa"}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
//#region src/cors.ts
|
||||
/**
|
||||
* Canonical CORS configuration for Supabase Edge Functions
|
||||
*
|
||||
* This module exports CORS headers that stay synchronized with the Supabase SDK.
|
||||
* When new headers are added to the SDK, they are automatically included here,
|
||||
* preventing CORS errors in Edge Functions.
|
||||
*
|
||||
* @example Basic usage
|
||||
* ```typescript
|
||||
* import { corsHeaders } from '@supabase/supabase-js/cors'
|
||||
*
|
||||
* Deno.serve(async (req) => {
|
||||
* if (req.method === 'OPTIONS') {
|
||||
* return new Response('ok', { headers: corsHeaders })
|
||||
* }
|
||||
*
|
||||
* return new Response(
|
||||
* JSON.stringify({ data: 'Hello' }),
|
||||
* { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
* )
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @module cors
|
||||
*/
|
||||
/**
|
||||
* All custom headers sent by the Supabase SDK.
|
||||
* These headers need to be included in CORS configuration to prevent preflight failures.
|
||||
*
|
||||
* Headers:
|
||||
* - authorization: Bearer token for authentication
|
||||
* - x-client-info: Library version information
|
||||
* - apikey: Project API key
|
||||
* - content-type: Standard HTTP content type
|
||||
* - x-retry-count: Retry attempt number sent by postgrest-js on retried requests
|
||||
*/
|
||||
const SUPABASE_HEADERS = [
|
||||
"authorization",
|
||||
"x-client-info",
|
||||
"apikey",
|
||||
"content-type",
|
||||
"x-retry-count"
|
||||
].join(", ");
|
||||
/**
|
||||
* All HTTP methods used by the Supabase SDK
|
||||
*/
|
||||
const SUPABASE_METHODS = [
|
||||
"GET",
|
||||
"POST",
|
||||
"PUT",
|
||||
"PATCH",
|
||||
"DELETE",
|
||||
"OPTIONS"
|
||||
].join(", ");
|
||||
/**
|
||||
* Default CORS headers for Supabase Edge Functions.
|
||||
*
|
||||
* Includes all headers sent by Supabase client libraries and allows all standard HTTP methods.
|
||||
* Use this for simple CORS configurations with wildcard origin.
|
||||
*
|
||||
* @example Basic usage
|
||||
* ```typescript
|
||||
* import { corsHeaders } from '@supabase/supabase-js/cors'
|
||||
*
|
||||
* Deno.serve(async (req) => {
|
||||
* if (req.method === 'OPTIONS') {
|
||||
* return new Response('ok', { headers: corsHeaders })
|
||||
* }
|
||||
*
|
||||
* return new Response(
|
||||
* JSON.stringify({ data: 'Hello' }),
|
||||
* { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
* )
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @category Edge Functions
|
||||
*/
|
||||
const corsHeaders = {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Headers": SUPABASE_HEADERS,
|
||||
"Access-Control-Allow-Methods": SUPABASE_METHODS
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { corsHeaders };
|
||||
//# sourceMappingURL=cors.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cors.mjs","names":["corsHeaders: CorsHeaders"],"sources":["../src/cors.ts"],"sourcesContent":["/**\n * Canonical CORS configuration for Supabase Edge Functions\n *\n * This module exports CORS headers that stay synchronized with the Supabase SDK.\n * When new headers are added to the SDK, they are automatically included here,\n * preventing CORS errors in Edge Functions.\n *\n * @example Basic usage\n * ```typescript\n * import { corsHeaders } from '@supabase/supabase-js/cors'\n *\n * Deno.serve(async (req) => {\n * if (req.method === 'OPTIONS') {\n * return new Response('ok', { headers: corsHeaders })\n * }\n *\n * return new Response(\n * JSON.stringify({ data: 'Hello' }),\n * { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n * )\n * })\n * ```\n *\n * @module cors\n */\n\n/**\n * All custom headers sent by the Supabase SDK.\n * These headers need to be included in CORS configuration to prevent preflight failures.\n *\n * Headers:\n * - authorization: Bearer token for authentication\n * - x-client-info: Library version information\n * - apikey: Project API key\n * - content-type: Standard HTTP content type\n * - x-retry-count: Retry attempt number sent by postgrest-js on retried requests\n */\nconst SUPABASE_HEADERS = [\n 'authorization',\n 'x-client-info',\n 'apikey',\n 'content-type',\n 'x-retry-count',\n].join(', ')\n\n/**\n * All HTTP methods used by the Supabase SDK\n */\nconst SUPABASE_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'].join(', ')\n\n/**\n * Type representing CORS headers as a record of header names to values\n */\nexport type CorsHeaders = Record<string, string>\n\n/**\n * Default CORS headers for Supabase Edge Functions.\n *\n * Includes all headers sent by Supabase client libraries and allows all standard HTTP methods.\n * Use this for simple CORS configurations with wildcard origin.\n *\n * @example Basic usage\n * ```typescript\n * import { corsHeaders } from '@supabase/supabase-js/cors'\n *\n * Deno.serve(async (req) => {\n * if (req.method === 'OPTIONS') {\n * return new Response('ok', { headers: corsHeaders })\n * }\n *\n * return new Response(\n * JSON.stringify({ data: 'Hello' }),\n * { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n * )\n * })\n * ```\n *\n * @category Edge Functions\n */\nexport const corsHeaders: CorsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': SUPABASE_HEADERS,\n 'Access-Control-Allow-Methods': SUPABASE_METHODS,\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,MAAM,mBAAmB;CACvB;CACA;CACA;CACA;CACA;CACD,CAAC,KAAK,KAAK;;;;AAKZ,MAAM,mBAAmB;CAAC;CAAO;CAAQ;CAAO;CAAS;CAAU;CAAU,CAAC,KAAK,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;AA+BxF,MAAaA,cAA2B;CACtC,+BAA+B;CAC/B,gCAAgC;CAChC,gCAAgC;CACjC"}
|
||||
+1575
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
+776
@@ -0,0 +1,776 @@
|
||||
import { FunctionInvokeOptions, FunctionRegion, FunctionsClient, FunctionsError, FunctionsFetchError, FunctionsHttpError, FunctionsRelayError } from "@supabase/functions-js";
|
||||
import { PostgrestBuilder, PostgrestClient, PostgrestError, PostgrestError as PostgrestError$1, PostgrestFilterBuilder, PostgrestFilterBuilder as PostgrestFilterBuilder$1, PostgrestMaybeSingleResponse, PostgrestQueryBuilder, PostgrestQueryBuilder as PostgrestQueryBuilder$1, PostgrestResponse, PostgrestSingleResponse, PostgrestTransformBuilder } from "@supabase/postgrest-js";
|
||||
import { RealtimeChannel, RealtimeChannelOptions, RealtimeClient, RealtimeClientOptions, RealtimeRemoveChannelResponse } from "@supabase/realtime-js";
|
||||
import { StorageApiError, StorageClient, StorageClientOptions } from "@supabase/storage-js";
|
||||
import { AuthClient, GoTrueClientOptions, Session as AuthSession, User as AuthUser } from "@supabase/auth-js";
|
||||
export * from "@supabase/realtime-js";
|
||||
export * from "@supabase/auth-js";
|
||||
|
||||
//#region src/lib/rest/types/common/common.d.ts
|
||||
|
||||
type GenericRelationship = {
|
||||
foreignKeyName: string;
|
||||
columns: string[];
|
||||
isOneToOne?: boolean;
|
||||
referencedRelation: string;
|
||||
referencedColumns: string[];
|
||||
};
|
||||
type GenericTable = {
|
||||
Row: Record<string, unknown>;
|
||||
Insert: Record<string, unknown>;
|
||||
Update: Record<string, unknown>;
|
||||
Relationships: GenericRelationship[];
|
||||
};
|
||||
type GenericUpdatableView = {
|
||||
Row: Record<string, unknown>;
|
||||
Insert: Record<string, unknown>;
|
||||
Update: Record<string, unknown>;
|
||||
Relationships: GenericRelationship[];
|
||||
};
|
||||
type GenericNonUpdatableView = {
|
||||
Row: Record<string, unknown>;
|
||||
Relationships: GenericRelationship[];
|
||||
};
|
||||
type GenericView = GenericUpdatableView | GenericNonUpdatableView;
|
||||
type GenericSetofOption = {
|
||||
isSetofReturn?: boolean | undefined;
|
||||
isOneToOne?: boolean | undefined;
|
||||
isNotNullable?: boolean | undefined;
|
||||
to: string;
|
||||
from: string;
|
||||
};
|
||||
type GenericFunction = {
|
||||
Args: Record<string, unknown> | never;
|
||||
Returns: unknown;
|
||||
SetofOptions?: GenericSetofOption;
|
||||
};
|
||||
type GenericSchema = {
|
||||
Tables: Record<string, GenericTable>;
|
||||
Views: Record<string, GenericView>;
|
||||
Functions: Record<string, GenericFunction>;
|
||||
};
|
||||
//#endregion
|
||||
//#region src/lib/types.d.ts
|
||||
interface SupabaseAuthClientOptions extends GoTrueClientOptions {}
|
||||
type Fetch = typeof fetch;
|
||||
/**
|
||||
* Configuration options for trace context propagation.
|
||||
*
|
||||
* Enables distributed tracing across Supabase services using W3C Trace Context
|
||||
* and OpenTelemetry standards. When enabled, the SDK automatically attaches
|
||||
* trace context headers (`traceparent`, `tracestate`, `baggage`) to outgoing
|
||||
* requests to Supabase domains. The resulting `trace_id` appears in API
|
||||
* Gateway and Edge Function logs, so logs forwarded through Log Drains can
|
||||
* be correlated back to the originating client-side span.
|
||||
*
|
||||
* Requires `@opentelemetry/api` to be installed in the consuming application.
|
||||
* If it is not installed, or there is no active context at request time,
|
||||
* propagation silently no-ops.
|
||||
*
|
||||
* @example Enable with defaults
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* tracePropagation: { enabled: true },
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @see https://www.w3.org/TR/trace-context/
|
||||
* @see https://opentelemetry.io/docs/concepts/context-propagation/
|
||||
* @see https://supabase.com/docs/guides/telemetry/client-side-tracing
|
||||
*/
|
||||
interface TracePropagationOptions {
|
||||
/**
|
||||
* Enable trace propagation. Disabled by default.
|
||||
*
|
||||
* When enabled, automatically detects and propagates active trace context
|
||||
* from the OpenTelemetry API to outgoing Supabase requests. Trace context
|
||||
* is only propagated to Supabase domains (`*.supabase.co`, `*.supabase.in`,
|
||||
* `localhost`) for security — third-party hosts never receive trace headers.
|
||||
*
|
||||
* @default false
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* tracePropagation: { enabled: true },
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
enabled?: boolean;
|
||||
/**
|
||||
* Respect upstream sampling decisions.
|
||||
*
|
||||
* When true (the default), trace context is not propagated if the upstream
|
||||
* trace indicates non-sampling (sampled flag = `0` in the `traceparent`
|
||||
* header). This avoids overhead when traces are being recorded but dropped.
|
||||
*
|
||||
* Set to `false` to always propagate, regardless of the sampling decision
|
||||
* — useful when you want every Supabase request tagged with a `trace_id`
|
||||
* for log correlation, even if the trace itself will not be exported.
|
||||
*
|
||||
* @default true
|
||||
*
|
||||
* @example Always propagate, ignore sampling
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* tracePropagation: { enabled: true, respectSamplingDecision: false },
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
respectSamplingDecision?: boolean;
|
||||
}
|
||||
type SupabaseClientOptions<SchemaName> = {
|
||||
/**
|
||||
* The Postgres schema which your tables belong to. Must be on the list of exposed schemas in Supabase. Defaults to `public`.
|
||||
*/
|
||||
db?: {
|
||||
schema?: SchemaName;
|
||||
/**
|
||||
* Optional timeout in milliseconds for PostgREST requests.
|
||||
* When set, requests will automatically abort after this duration to prevent indefinite hangs.
|
||||
*
|
||||
* @example With timeout
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* db: { timeout: 30000 } // 30 second timeout
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
timeout?: number;
|
||||
/**
|
||||
* Maximum URL length in characters before warnings/errors are triggered.
|
||||
* Defaults to 8000 characters. Used to provide helpful hints when URLs
|
||||
* exceed server limits.
|
||||
*
|
||||
* @example With custom URL length limit
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* db: { urlLengthLimit: 10000 } // Custom limit
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
urlLengthLimit?: number;
|
||||
};
|
||||
auth?: {
|
||||
/**
|
||||
* Automatically refreshes the token for logged-in users. Defaults to true.
|
||||
*/
|
||||
autoRefreshToken?: boolean;
|
||||
/**
|
||||
* Optional key name used for storing tokens in local storage.
|
||||
*/
|
||||
storageKey?: string;
|
||||
/**
|
||||
* Whether to persist a logged-in session to storage. Defaults to true.
|
||||
*/
|
||||
persistSession?: boolean;
|
||||
/**
|
||||
* Detect a session from the URL. Used for OAuth login callbacks. Defaults to true.
|
||||
*
|
||||
* Can be set to a function to provide custom logic for determining if a URL contains
|
||||
* a Supabase auth callback. The function receives the current URL and parsed parameters,
|
||||
* and should return true if the URL should be processed as a Supabase auth callback.
|
||||
*
|
||||
* This is useful when your app uses other OAuth providers (e.g., Facebook Login) that
|
||||
* also return access_token in the URL fragment, which would otherwise be incorrectly
|
||||
* intercepted by Supabase Auth.
|
||||
*
|
||||
* @example With custom detection logic
|
||||
* ```ts
|
||||
* detectSessionInUrl: (url, params) => {
|
||||
* // Ignore Facebook OAuth redirects
|
||||
* if (url.pathname === '/facebook/redirect') return false
|
||||
* // Use default detection for other URLs
|
||||
* return Boolean(params.access_token || params.error_description)
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
detectSessionInUrl?: boolean | ((url: URL, params: {
|
||||
[parameter: string]: string;
|
||||
}) => boolean);
|
||||
/**
|
||||
* A storage provider. Used to store the logged-in session.
|
||||
*/
|
||||
storage?: SupabaseAuthClientOptions['storage'];
|
||||
/**
|
||||
* A storage provider to store the user profile separately from the session.
|
||||
* Useful when you need to store the session information in cookies,
|
||||
* without bloating the data with the redundant user object.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
userStorage?: SupabaseAuthClientOptions['userStorage'];
|
||||
/**
|
||||
* OAuth flow to use - defaults to implicit flow. PKCE is recommended for mobile and server-side applications.
|
||||
*/
|
||||
flowType?: SupabaseAuthClientOptions['flowType'];
|
||||
/**
|
||||
* If debug messages for authentication client are emitted. Can be used to inspect the behavior of the library.
|
||||
*/
|
||||
debug?: SupabaseAuthClientOptions['debug'];
|
||||
/**
|
||||
* Provide your own locking mechanism based on the environment. By default
|
||||
* the auth client coordinates refreshes itself and the server resolves
|
||||
* cross-tab races. Passing a custom `lock` opts into a legacy path that
|
||||
* wraps every auth operation in your supplied lock.
|
||||
*
|
||||
* @deprecated Custom locks still work in v2.x for backwards compatibility.
|
||||
* The legacy lock path will be removed in v3 — drop this option from your
|
||||
* `createClient` options before upgrading.
|
||||
*/
|
||||
lock?: SupabaseAuthClientOptions['lock'];
|
||||
/**
|
||||
* If there is an error with the query, throwOnError will reject the promise by
|
||||
* throwing the error instead of returning it as part of a successful response.
|
||||
*/
|
||||
throwOnError?: SupabaseAuthClientOptions['throwOnError'];
|
||||
/**
|
||||
* Opt-in flags for experimental features. These APIs may change without
|
||||
* notice and are disabled by default.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
experimental?: SupabaseAuthClientOptions['experimental'];
|
||||
/**
|
||||
* Maximum time in milliseconds to wait for acquiring the custom lock
|
||||
* supplied via `lock`. Only consulted when a custom `lock` is passed.
|
||||
*
|
||||
* @default 5000
|
||||
*
|
||||
* @deprecated Only used by the legacy lock path. Will be removed in v3
|
||||
* along with the `lock` option.
|
||||
*/
|
||||
lockAcquireTimeout?: SupabaseAuthClientOptions['lockAcquireTimeout'];
|
||||
/**
|
||||
* If true, skips automatic initialization in the auth client constructor.
|
||||
* Useful for SSR contexts where initialization timing must be controlled to
|
||||
* prevent race conditions with HTTP response generation.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
skipAutoInitialize?: SupabaseAuthClientOptions['skipAutoInitialize'];
|
||||
};
|
||||
/**
|
||||
* Options passed to the realtime-js instance
|
||||
*/
|
||||
realtime?: RealtimeClientOptions;
|
||||
storage?: StorageClientOptions;
|
||||
global?: {
|
||||
/**
|
||||
* A custom `fetch` implementation.
|
||||
*/
|
||||
fetch?: Fetch;
|
||||
/**
|
||||
* Optional headers for initializing the client.
|
||||
*/
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
/**
|
||||
* Optional function for using a third-party authentication system with
|
||||
* Supabase. The function should return an access token or ID token (JWT) by
|
||||
* obtaining it from the third-party auth SDK. Note that this
|
||||
* function may be called concurrently and many times. Use memoization and
|
||||
* locking techniques if this is not supported by the SDKs.
|
||||
*
|
||||
* When set, the `auth` namespace of the Supabase client cannot be used.
|
||||
* Create another client if you wish to use Supabase Auth and third-party
|
||||
* authentications concurrently in the same application.
|
||||
*/
|
||||
accessToken?: () => Promise<string | null>;
|
||||
/**
|
||||
* Enable OpenTelemetry / W3C trace context propagation to Supabase services.
|
||||
*
|
||||
* Disabled by default. Pass `true` for the common case (auto-detect an
|
||||
* active OpenTelemetry context and inject `traceparent` / `tracestate` /
|
||||
* `baggage` headers) or an object for fine-grained control.
|
||||
*
|
||||
* Requires `@opentelemetry/api` to be installed in your application; if
|
||||
* not present, the SDK silently no-ops. Trace headers are only attached
|
||||
* to requests targeting Supabase domains, so third-party hosts called
|
||||
* through a custom `fetch` are never tagged.
|
||||
*
|
||||
* The resulting `trace_id` appears in Supabase logs (API Gateway, Edge
|
||||
* Functions), letting you correlate client-side spans with server-side
|
||||
* log entries — including logs forwarded via Log Drains.
|
||||
*
|
||||
* @example Shorthand — opt in with defaults
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient(url, key, { tracePropagation: true })
|
||||
* ```
|
||||
*
|
||||
* @example With an active OpenTelemetry span
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import { trace } from '@opentelemetry/api'
|
||||
*
|
||||
* const supabase = createClient(url, key, { tracePropagation: true })
|
||||
* const tracer = trace.getTracer('my-app')
|
||||
*
|
||||
* await tracer.startActiveSpan('fetch-users', async (span) => {
|
||||
* // Request carries the active trace context.
|
||||
* const { data, error } = await supabase.from('users').select('*')
|
||||
* span.end()
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @example Advanced — always propagate, even for non-sampled traces
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* tracePropagation: { enabled: true, respectSamplingDecision: false },
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @see https://supabase.com/docs/guides/telemetry/client-side-tracing
|
||||
* @see https://www.w3.org/TR/trace-context/
|
||||
*/
|
||||
tracePropagation?: TracePropagationOptions | boolean;
|
||||
};
|
||||
/**
|
||||
* Helper types for query results.
|
||||
*/
|
||||
type QueryResult<T> = T extends PromiseLike<infer U> ? U : never;
|
||||
type QueryData<T> = T extends PromiseLike<{
|
||||
data: infer U;
|
||||
}> ? Exclude<U, null> : never;
|
||||
type QueryError = PostgrestError$1;
|
||||
/**
|
||||
* Strips internal Supabase metadata from Database types.
|
||||
* Useful for libraries defining generic constraints on Database types.
|
||||
*
|
||||
* @example Stripping internal Supabase metadata
|
||||
* ```typescript
|
||||
* type CleanDB = DatabaseWithoutInternals<Database>
|
||||
* ```
|
||||
*/
|
||||
type DatabaseWithoutInternals<DB> = Omit<DB, '__InternalSupabase'>;
|
||||
//#endregion
|
||||
//#region src/lib/helpers.d.ts
|
||||
type ResolvedSupabaseClientOptions<SchemaName> = Omit<Required<SupabaseClientOptions<SchemaName>>, 'tracePropagation'> & {
|
||||
tracePropagation: TracePropagationOptions;
|
||||
};
|
||||
//#endregion
|
||||
//#region src/lib/SupabaseAuthClient.d.ts
|
||||
declare class SupabaseAuthClient extends AuthClient {
|
||||
constructor(options: SupabaseAuthClientOptions);
|
||||
}
|
||||
//#endregion
|
||||
//#region src/lib/rest/types/common/rpc.d.ts
|
||||
type IsMatchingArgs<FnArgs extends GenericFunction['Args'], PassedArgs extends GenericFunction['Args']> = [FnArgs] extends [Record<PropertyKey, never>] ? PassedArgs extends Record<PropertyKey, never> ? true : false : keyof PassedArgs extends keyof FnArgs ? PassedArgs extends FnArgs ? true : false : false;
|
||||
type MatchingFunctionArgs<Fn$1 extends GenericFunction, Args extends GenericFunction['Args']> = Fn$1 extends {
|
||||
Args: infer A extends GenericFunction['Args'];
|
||||
} ? IsMatchingArgs<A, Args> extends true ? Fn$1 : never : false;
|
||||
type FindMatchingFunctionByArgs<FnUnion, Args extends GenericFunction['Args']> = FnUnion extends infer Fn extends GenericFunction ? MatchingFunctionArgs<Fn, Args> : false;
|
||||
type TablesAndViews<Schema extends GenericSchema> = Schema['Tables'] & Exclude<Schema['Views'], ''>;
|
||||
type UnionToIntersection<U$1> = (U$1 extends any ? (k: U$1) => void : never) extends ((k: infer I) => void) ? I : never;
|
||||
type LastOf<T> = UnionToIntersection<T extends any ? () => T : never> extends (() => infer R) ? R : never;
|
||||
type IsAny<T> = 0 extends 1 & T ? true : false;
|
||||
type ExactMatch<T, S> = [T] extends [S] ? ([S] extends [T] ? true : false) : false;
|
||||
type ExtractExactFunction<Fns, Args> = Fns extends infer F ? F extends GenericFunction ? ExactMatch<F['Args'], Args> extends true ? F : never : never : never;
|
||||
type IsNever<T> = [T] extends [never] ? true : false;
|
||||
type RpcFunctionNotFound<FnName> = {
|
||||
Row: any;
|
||||
Result: {
|
||||
error: true;
|
||||
} & "Couldn't infer function definition matching provided arguments";
|
||||
RelationName: FnName;
|
||||
Relationships: null;
|
||||
};
|
||||
type CrossSchemaError<TableRef extends string> = {
|
||||
error: true;
|
||||
} & `Function returns SETOF from a different schema ('${TableRef}'). Use .overrideTypes<YourReturnType>() to specify the return type explicitly.`;
|
||||
type GetRpcFunctionFilterBuilderByArgs<Schema extends GenericSchema, FnName extends string & keyof Schema['Functions'], Args> = {
|
||||
0: Schema['Functions'][FnName];
|
||||
1: IsAny<Schema> extends true ? any : IsNever<Args> extends true ? IsNever<ExtractExactFunction<Schema['Functions'][FnName], Args>> extends true ? LastOf<Schema['Functions'][FnName]> : ExtractExactFunction<Schema['Functions'][FnName], Args> : Args extends Record<PropertyKey, never> ? LastOf<Schema['Functions'][FnName]> : Args extends GenericFunction['Args'] ? IsNever<LastOf<FindMatchingFunctionByArgs<Schema['Functions'][FnName], Args>>> extends true ? LastOf<Schema['Functions'][FnName]> : LastOf<FindMatchingFunctionByArgs<Schema['Functions'][FnName], Args>> : ExtractExactFunction<Schema['Functions'][FnName], Args> extends GenericFunction ? ExtractExactFunction<Schema['Functions'][FnName], Args> : any;
|
||||
}[1] extends infer Fn ? IsAny<Fn> extends true ? {
|
||||
Row: any;
|
||||
Result: any;
|
||||
RelationName: FnName;
|
||||
Relationships: null;
|
||||
} : Fn extends GenericFunction ? {
|
||||
Row: Fn['SetofOptions'] extends GenericSetofOption ? Fn['SetofOptions']['to'] extends keyof TablesAndViews<Schema> ? TablesAndViews<Schema>[Fn['SetofOptions']['to']]['Row'] : Fn['Returns'] extends any[] ? Fn['Returns'][number] extends Record<string, unknown> ? Fn['Returns'][number] : CrossSchemaError<Fn['SetofOptions']['to'] & string> : Fn['Returns'] extends Record<string, unknown> ? Fn['Returns'] : CrossSchemaError<Fn['SetofOptions']['to'] & string> : Fn['Returns'] extends any[] ? Fn['Returns'][number] extends Record<string, unknown> ? Fn['Returns'][number] : never : Fn['Returns'] extends Record<string, unknown> ? Fn['Returns'] : never;
|
||||
Result: Fn['SetofOptions'] extends GenericSetofOption ? Fn['SetofOptions']['isSetofReturn'] extends true ? Fn['SetofOptions']['isOneToOne'] extends true ? Fn['Returns'][] : Fn['Returns'] : Fn['Returns'] : Fn['Returns'];
|
||||
RelationName: Fn['SetofOptions'] extends GenericSetofOption ? Fn['SetofOptions']['to'] : FnName;
|
||||
Relationships: Fn['SetofOptions'] extends GenericSetofOption ? Fn['SetofOptions']['to'] extends keyof Schema['Tables'] ? Schema['Tables'][Fn['SetofOptions']['to']]['Relationships'] : Fn['SetofOptions']['to'] extends keyof Schema['Views'] ? Schema['Views'][Fn['SetofOptions']['to']]['Relationships'] : null : null;
|
||||
} : Fn extends false ? RpcFunctionNotFound<FnName> : RpcFunctionNotFound<FnName> : RpcFunctionNotFound<FnName>;
|
||||
//#endregion
|
||||
//#region src/SupabaseClient.d.ts
|
||||
/**
|
||||
* Supabase Client.
|
||||
*
|
||||
* An isomorphic Javascript client for interacting with Postgres.
|
||||
*/
|
||||
declare class SupabaseClient<Database = any, SchemaNameOrClientOptions extends (string & keyof Omit<Database, '__InternalSupabase'>) | {
|
||||
PostgrestVersion: string;
|
||||
} = ('public' extends keyof Omit<Database, '__InternalSupabase'> ? 'public' : string & keyof Omit<Database, '__InternalSupabase'>), SchemaName extends string & keyof Omit<Database, '__InternalSupabase'> = (SchemaNameOrClientOptions extends string & keyof Omit<Database, '__InternalSupabase'> ? SchemaNameOrClientOptions : 'public' extends keyof Omit<Database, '__InternalSupabase'> ? 'public' : string & keyof Omit<Omit<Database, '__InternalSupabase'>, '__InternalSupabase'>), Schema extends (Omit<Database, '__InternalSupabase'>[SchemaName] extends GenericSchema ? Omit<Database, '__InternalSupabase'>[SchemaName] : never) = (Omit<Database, '__InternalSupabase'>[SchemaName] extends GenericSchema ? Omit<Database, '__InternalSupabase'>[SchemaName] : never), ClientOptions extends {
|
||||
PostgrestVersion: string;
|
||||
} = (SchemaNameOrClientOptions extends string & keyof Omit<Database, '__InternalSupabase'> ? Database extends {
|
||||
__InternalSupabase: {
|
||||
PostgrestVersion: string;
|
||||
};
|
||||
} ? Database['__InternalSupabase'] : {
|
||||
PostgrestVersion: '12';
|
||||
} : SchemaNameOrClientOptions extends {
|
||||
PostgrestVersion: string;
|
||||
} ? SchemaNameOrClientOptions : never)> {
|
||||
protected supabaseUrl: string;
|
||||
protected supabaseKey: string;
|
||||
/**
|
||||
* Supabase Auth allows you to create and manage user sessions for access to data that is secured by access policies.
|
||||
*/
|
||||
auth: SupabaseAuthClient;
|
||||
realtime: RealtimeClient;
|
||||
/**
|
||||
* Supabase Storage allows you to manage user-generated content, such as photos or videos.
|
||||
*/
|
||||
storage: StorageClient;
|
||||
protected realtimeUrl: URL;
|
||||
protected authUrl: URL;
|
||||
protected storageUrl: URL;
|
||||
protected functionsUrl: URL;
|
||||
protected rest: PostgrestClient<Database, ClientOptions, SchemaName>;
|
||||
protected storageKey: string;
|
||||
protected fetch?: Fetch;
|
||||
protected functionsFetch?: Fetch;
|
||||
protected changedAccessToken?: string;
|
||||
protected accessToken?: () => Promise<string | null>;
|
||||
protected headers: Record<string, string>;
|
||||
protected settings?: ResolvedSupabaseClientOptions<SchemaName>;
|
||||
/**
|
||||
* Create a new client for use in the browser.
|
||||
*
|
||||
* @category Initializing
|
||||
*
|
||||
* @param supabaseUrl The unique Supabase URL which is supplied when you create a new project in your project dashboard.
|
||||
* @param supabaseKey The unique Supabase Key which is supplied when you create a new project in your project dashboard.
|
||||
* @param options Optional configuration for the client:
|
||||
* - `db.schema` — You can switch in between schemas. The schema needs to be on the list of exposed schemas inside Supabase.
|
||||
* - `auth.autoRefreshToken` — Set to `true` if you want to automatically refresh the token before expiring.
|
||||
* - `auth.persistSession` — Set to `true` if you want to automatically save the user session into local storage.
|
||||
* - `auth.detectSessionInUrl` — Set to `true` if you want to automatically detect OAuth grants in the URL and sign in the user.
|
||||
* - `realtime` — Options passed along to the realtime-js constructor.
|
||||
* - `storage` — Options passed along to the storage-js constructor.
|
||||
* - `global.fetch` — A custom fetch implementation.
|
||||
* - `global.headers` — Any additional headers to send with each network request.
|
||||
*
|
||||
* @example Creating a client
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* // Create a single supabase client for interacting with your database
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
* ```
|
||||
*
|
||||
* @example With a custom domain
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* // Use a custom domain as the supabase URL
|
||||
* const supabase = createClient('https://my-custom-domain.com', 'your-publishable-key')
|
||||
* ```
|
||||
*
|
||||
* @example With additional parameters
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const options = {
|
||||
* db: {
|
||||
* schema: 'public',
|
||||
* },
|
||||
* auth: {
|
||||
* autoRefreshToken: true,
|
||||
* persistSession: true,
|
||||
* detectSessionInUrl: true
|
||||
* },
|
||||
* global: {
|
||||
* headers: { 'x-my-custom-header': 'my-app-name' },
|
||||
* },
|
||||
* }
|
||||
* const supabase = createClient("https://xyzcompany.supabase.co", "your-publishable-key", options)
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription With custom schemas
|
||||
* By default the API server points to the `public` schema. You can enable other database schemas within the Dashboard.
|
||||
* Go to [Settings > API > Exposed schemas](/dashboard/project/_/settings/api) and add the schema which you want to expose to the API.
|
||||
*
|
||||
* Note: each client connection can only access a single schema, so the code above can access the `other_schema` schema but cannot access the `public` schema.
|
||||
*
|
||||
* @example With custom schemas
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
* // Provide a custom schema. Defaults to "public".
|
||||
* db: { schema: 'other_schema' }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription Custom fetch implementation
|
||||
* `supabase-js` uses the runtime's global `fetch` to make HTTP requests,
|
||||
* but an alternative `fetch` implementation can be provided as an option.
|
||||
* This is useful in environments where the global `fetch` is unavailable or where you want to customize request behavior.
|
||||
*
|
||||
* @example Custom fetch implementation
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
* global: { fetch: fetch.bind(globalThis) }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription React Native options with AsyncStorage
|
||||
* For React Native we recommend using `AsyncStorage` as the storage implementation for Supabase Auth.
|
||||
*
|
||||
* @example React Native options with AsyncStorage
|
||||
* ```js
|
||||
* import 'react-native-url-polyfill/auto'
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
*
|
||||
* const supabase = createClient("https://xyzcompany.supabase.co", "your-publishable-key", {
|
||||
* auth: {
|
||||
* storage: AsyncStorage,
|
||||
* autoRefreshToken: true,
|
||||
* persistSession: true,
|
||||
* detectSessionInUrl: false,
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription React Native options with Expo SecureStore
|
||||
* If you wish to encrypt the user's session information, you can use `aes-js` and store the encryption key in Expo SecureStore.
|
||||
* The `aes-js` library, a reputable JavaScript-only implementation of the AES encryption algorithm in CTR mode.
|
||||
* A new 256-bit encryption key is generated using the `react-native-get-random-values` library.
|
||||
* This key is stored inside Expo's SecureStore, while the value is encrypted and placed inside AsyncStorage.
|
||||
*
|
||||
* Please make sure that:
|
||||
* - You keep the `expo-secure-store`, `aes-js` and `react-native-get-random-values` libraries up-to-date.
|
||||
* - Choose the correct [`SecureStoreOptions`](https://docs.expo.dev/versions/latest/sdk/securestore/#securestoreoptions) for your app's needs.
|
||||
* E.g. [`SecureStore.WHEN_UNLOCKED`](https://docs.expo.dev/versions/latest/sdk/securestore/#securestorewhen_unlocked) regulates when the data can be accessed.
|
||||
* - Carefully consider optimizations or other modifications to the above example, as those can lead to introducing subtle security vulnerabilities.
|
||||
*
|
||||
* @example React Native options with Expo SecureStore
|
||||
* ```ts
|
||||
* import 'react-native-url-polyfill/auto'
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
* import * as SecureStore from 'expo-secure-store';
|
||||
* import * as aesjs from 'aes-js';
|
||||
* import 'react-native-get-random-values';
|
||||
*
|
||||
* // As Expo's SecureStore does not support values larger than 2048
|
||||
* // bytes, an AES-256 key is generated and stored in SecureStore, while
|
||||
* // it is used to encrypt/decrypt values stored in AsyncStorage.
|
||||
* class LargeSecureStore {
|
||||
* private async _encrypt(key: string, value: string) {
|
||||
* const encryptionKey = crypto.getRandomValues(new Uint8Array(256 / 8));
|
||||
*
|
||||
* const cipher = new aesjs.ModeOfOperation.ctr(encryptionKey, new aesjs.Counter(1));
|
||||
* const encryptedBytes = cipher.encrypt(aesjs.utils.utf8.toBytes(value));
|
||||
*
|
||||
* await SecureStore.setItemAsync(key, aesjs.utils.hex.fromBytes(encryptionKey));
|
||||
*
|
||||
* return aesjs.utils.hex.fromBytes(encryptedBytes);
|
||||
* }
|
||||
*
|
||||
* private async _decrypt(key: string, value: string) {
|
||||
* const encryptionKeyHex = await SecureStore.getItemAsync(key);
|
||||
* if (!encryptionKeyHex) {
|
||||
* return encryptionKeyHex;
|
||||
* }
|
||||
*
|
||||
* const cipher = new aesjs.ModeOfOperation.ctr(aesjs.utils.hex.toBytes(encryptionKeyHex), new aesjs.Counter(1));
|
||||
* const decryptedBytes = cipher.decrypt(aesjs.utils.hex.toBytes(value));
|
||||
*
|
||||
* return aesjs.utils.utf8.fromBytes(decryptedBytes);
|
||||
* }
|
||||
*
|
||||
* async getItem(key: string) {
|
||||
* const encrypted = await AsyncStorage.getItem(key);
|
||||
* if (!encrypted) { return encrypted; }
|
||||
*
|
||||
* return await this._decrypt(key, encrypted);
|
||||
* }
|
||||
*
|
||||
* async removeItem(key: string) {
|
||||
* await AsyncStorage.removeItem(key);
|
||||
* await SecureStore.deleteItemAsync(key);
|
||||
* }
|
||||
*
|
||||
* async setItem(key: string, value: string) {
|
||||
* const encrypted = await this._encrypt(key, value);
|
||||
*
|
||||
* await AsyncStorage.setItem(key, encrypted);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* const supabase = createClient("https://xyzcompany.supabase.co", "your-publishable-key", {
|
||||
* auth: {
|
||||
* storage: new LargeSecureStore(),
|
||||
* autoRefreshToken: true,
|
||||
* persistSession: true,
|
||||
* detectSessionInUrl: false,
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example With a database query
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
*
|
||||
* const { data } = await supabase.from('profiles').select('*')
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription With OpenTelemetry tracing
|
||||
* Opt in to W3C trace context propagation so the `trace_id` from your
|
||||
* client-side spans is attached to Supabase requests and appears in API
|
||||
* Gateway and Edge Function logs. Requires `@opentelemetry/api` to be
|
||||
* installed in your application. See [Tracing with the JS SDK](https://supabase.com/docs/guides/telemetry/client-side-tracing).
|
||||
*
|
||||
* @example With OpenTelemetry tracing
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import { trace } from '@opentelemetry/api'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
* tracePropagation: true,
|
||||
* })
|
||||
*
|
||||
* const tracer = trace.getTracer('my-app')
|
||||
*
|
||||
* await tracer.startActiveSpan('fetch-users', async (span) => {
|
||||
* // Outgoing request carries the active trace context.
|
||||
* const { data, error } = await supabase.from('users').select('*')
|
||||
* span.end()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
constructor(supabaseUrl: string, supabaseKey: string, options?: SupabaseClientOptions<SchemaName>);
|
||||
/**
|
||||
* Supabase Functions allows you to deploy and invoke edge functions.
|
||||
*/
|
||||
get functions(): FunctionsClient;
|
||||
from<TableName extends string & keyof Schema['Tables'], Table extends Schema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder$1<ClientOptions, Schema, Table, TableName>;
|
||||
from<ViewName extends string & keyof Schema['Views'], View extends Schema['Views'][ViewName]>(relation: ViewName): PostgrestQueryBuilder$1<ClientOptions, Schema, View, ViewName>;
|
||||
/**
|
||||
* Select a schema to query or perform an function (rpc) call.
|
||||
*
|
||||
* The schema needs to be on the list of exposed schemas inside Supabase.
|
||||
*
|
||||
* @param schema - The schema to query
|
||||
*/
|
||||
schema<DynamicSchema extends string & keyof Omit<Database, '__InternalSupabase'>>(schema: DynamicSchema): PostgrestClient<Database, ClientOptions, DynamicSchema, Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any>;
|
||||
/**
|
||||
* Perform a function call.
|
||||
*
|
||||
* @param fn - The function name to call
|
||||
* @param args - The arguments to pass to the function call
|
||||
* @param options - Named parameters
|
||||
* @param options.head - When set to `true`, `data` will not be returned.
|
||||
* Useful if you only need the count.
|
||||
* @param options.get - When set to `true`, the function will be called with
|
||||
* read-only access mode.
|
||||
* @param options.count - Count algorithm to use to count rows returned by the
|
||||
* function. Only applicable for [set-returning
|
||||
* functions](https://www.postgresql.org/docs/current/functions-srf.html).
|
||||
*
|
||||
* `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the
|
||||
* hood.
|
||||
*
|
||||
* `"planned"`: Approximated but fast count algorithm. Uses the Postgres
|
||||
* statistics under the hood.
|
||||
*
|
||||
* `"estimated"`: Uses exact count for low numbers and planned count for high
|
||||
* numbers.
|
||||
*/
|
||||
rpc<FnName extends string & keyof Schema['Functions'], Args extends Schema['Functions'][FnName]['Args'] = never, FilterBuilder extends GetRpcFunctionFilterBuilderByArgs<Schema, FnName, Args> = GetRpcFunctionFilterBuilderByArgs<Schema, FnName, Args>>(fn: FnName, args?: Args, options?: {
|
||||
head?: boolean;
|
||||
get?: boolean;
|
||||
count?: 'exact' | 'planned' | 'estimated';
|
||||
}): PostgrestFilterBuilder$1<ClientOptions, Schema, FilterBuilder['Row'], FilterBuilder['Result'], FilterBuilder['RelationName'], FilterBuilder['Relationships'], 'RPC'>;
|
||||
/**
|
||||
* Creates a Realtime channel with Broadcast, Presence, and Postgres Changes.
|
||||
*
|
||||
* @param {string} name - The name of the Realtime channel.
|
||||
* @param {Object} opts - The options to pass to the Realtime channel.
|
||||
*
|
||||
* @category Realtime
|
||||
*/
|
||||
channel(name: string, opts?: RealtimeChannelOptions): RealtimeChannel;
|
||||
/**
|
||||
* Returns all Realtime channels.
|
||||
*
|
||||
* @category Realtime
|
||||
*
|
||||
* @example Get all channels
|
||||
* ```js
|
||||
* const channels = supabase.getChannels()
|
||||
* ```
|
||||
*/
|
||||
getChannels(): RealtimeChannel[];
|
||||
/**
|
||||
* Unsubscribes and removes Realtime channel from Realtime client.
|
||||
*
|
||||
* @param {RealtimeChannel} channel - The name of the Realtime channel.
|
||||
*
|
||||
*
|
||||
* @category Realtime
|
||||
*
|
||||
* @remarks
|
||||
* - Removing a channel is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
|
||||
*
|
||||
* @example Removes a channel
|
||||
* ```js
|
||||
* supabase.removeChannel(myChannel)
|
||||
* ```
|
||||
*/
|
||||
removeChannel(channel: RealtimeChannel): Promise<RealtimeRemoveChannelResponse>;
|
||||
/**
|
||||
* Unsubscribes and removes all Realtime channels from Realtime client.
|
||||
*
|
||||
* @category Realtime
|
||||
*
|
||||
* @remarks
|
||||
* - Removing channels is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
|
||||
*
|
||||
* @example Remove all channels
|
||||
* ```js
|
||||
* supabase.removeAllChannels()
|
||||
* ```
|
||||
*/
|
||||
removeAllChannels(): Promise<RealtimeRemoveChannelResponse[]>;
|
||||
/**
|
||||
* The raw session token — the custom `accessToken` result or the signed-in user's JWT —
|
||||
* or `null` when there is no session. Unlike {@link _getAccessToken} it does not fall back
|
||||
* to `supabaseKey`, so callers can distinguish "no session" from "has session".
|
||||
*/
|
||||
private _getSessionToken;
|
||||
private _getAccessToken;
|
||||
private _initSupabaseAuthClient;
|
||||
private _initRealtimeClient;
|
||||
private _listenForAuthEvents;
|
||||
private _handleTokenChanged;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/index.d.ts
|
||||
/**
|
||||
* Creates a new Supabase Client.
|
||||
*
|
||||
* @example Creating a Supabase client
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
* const { data, error } = await supabase.from('profiles').select('*')
|
||||
* ```
|
||||
*/
|
||||
declare const createClient: <Database = any, SchemaNameOrClientOptions extends (string & keyof Omit<Database, "__InternalSupabase">) | {
|
||||
PostgrestVersion: string;
|
||||
} = ("public" extends keyof Omit<Database, "__InternalSupabase"> ? "public" : string & keyof Omit<Database, "__InternalSupabase">), SchemaName extends string & keyof Omit<Database, "__InternalSupabase"> = (SchemaNameOrClientOptions extends string & keyof Omit<Database, "__InternalSupabase"> ? SchemaNameOrClientOptions : "public" extends keyof Omit<Database, "__InternalSupabase"> ? "public" : string & keyof Omit<Omit<Database, "__InternalSupabase">, "__InternalSupabase">)>(supabaseUrl: string, supabaseKey: string, options?: SupabaseClientOptions<SchemaName>) => SupabaseClient<Database, SchemaNameOrClientOptions, SchemaName>;
|
||||
//#endregion
|
||||
export { type AuthSession, type AuthUser, type DatabaseWithoutInternals, type FunctionInvokeOptions, FunctionRegion, FunctionsError, FunctionsFetchError, FunctionsHttpError, FunctionsRelayError, type PostgrestBuilder, PostgrestError, type PostgrestFilterBuilder, type PostgrestMaybeSingleResponse, type PostgrestQueryBuilder, type PostgrestResponse, type PostgrestSingleResponse, type PostgrestTransformBuilder, type QueryData, type QueryError, type QueryResult, StorageApiError, SupabaseClient, type SupabaseClientOptions, type TracePropagationOptions, createClient };
|
||||
//# sourceMappingURL=index.d.cts.map
|
||||
+1
File diff suppressed because one or more lines are too long
+776
@@ -0,0 +1,776 @@
|
||||
import { FunctionInvokeOptions, FunctionRegion, FunctionsClient, FunctionsError, FunctionsFetchError, FunctionsHttpError, FunctionsRelayError } from "@supabase/functions-js";
|
||||
import { PostgrestBuilder, PostgrestClient, PostgrestError, PostgrestError as PostgrestError$1, PostgrestFilterBuilder, PostgrestFilterBuilder as PostgrestFilterBuilder$1, PostgrestMaybeSingleResponse, PostgrestQueryBuilder, PostgrestQueryBuilder as PostgrestQueryBuilder$1, PostgrestResponse, PostgrestSingleResponse, PostgrestTransformBuilder } from "@supabase/postgrest-js";
|
||||
import { RealtimeChannel, RealtimeChannelOptions, RealtimeClient, RealtimeClientOptions, RealtimeRemoveChannelResponse } from "@supabase/realtime-js";
|
||||
import { StorageApiError, StorageClient, StorageClientOptions } from "@supabase/storage-js";
|
||||
import { AuthClient, GoTrueClientOptions, Session as AuthSession, User as AuthUser } from "@supabase/auth-js";
|
||||
export * from "@supabase/realtime-js";
|
||||
export * from "@supabase/auth-js";
|
||||
|
||||
//#region src/lib/rest/types/common/common.d.ts
|
||||
|
||||
type GenericRelationship = {
|
||||
foreignKeyName: string;
|
||||
columns: string[];
|
||||
isOneToOne?: boolean;
|
||||
referencedRelation: string;
|
||||
referencedColumns: string[];
|
||||
};
|
||||
type GenericTable = {
|
||||
Row: Record<string, unknown>;
|
||||
Insert: Record<string, unknown>;
|
||||
Update: Record<string, unknown>;
|
||||
Relationships: GenericRelationship[];
|
||||
};
|
||||
type GenericUpdatableView = {
|
||||
Row: Record<string, unknown>;
|
||||
Insert: Record<string, unknown>;
|
||||
Update: Record<string, unknown>;
|
||||
Relationships: GenericRelationship[];
|
||||
};
|
||||
type GenericNonUpdatableView = {
|
||||
Row: Record<string, unknown>;
|
||||
Relationships: GenericRelationship[];
|
||||
};
|
||||
type GenericView = GenericUpdatableView | GenericNonUpdatableView;
|
||||
type GenericSetofOption = {
|
||||
isSetofReturn?: boolean | undefined;
|
||||
isOneToOne?: boolean | undefined;
|
||||
isNotNullable?: boolean | undefined;
|
||||
to: string;
|
||||
from: string;
|
||||
};
|
||||
type GenericFunction = {
|
||||
Args: Record<string, unknown> | never;
|
||||
Returns: unknown;
|
||||
SetofOptions?: GenericSetofOption;
|
||||
};
|
||||
type GenericSchema = {
|
||||
Tables: Record<string, GenericTable>;
|
||||
Views: Record<string, GenericView>;
|
||||
Functions: Record<string, GenericFunction>;
|
||||
};
|
||||
//#endregion
|
||||
//#region src/lib/types.d.ts
|
||||
interface SupabaseAuthClientOptions extends GoTrueClientOptions {}
|
||||
type Fetch = typeof fetch;
|
||||
/**
|
||||
* Configuration options for trace context propagation.
|
||||
*
|
||||
* Enables distributed tracing across Supabase services using W3C Trace Context
|
||||
* and OpenTelemetry standards. When enabled, the SDK automatically attaches
|
||||
* trace context headers (`traceparent`, `tracestate`, `baggage`) to outgoing
|
||||
* requests to Supabase domains. The resulting `trace_id` appears in API
|
||||
* Gateway and Edge Function logs, so logs forwarded through Log Drains can
|
||||
* be correlated back to the originating client-side span.
|
||||
*
|
||||
* Requires `@opentelemetry/api` to be installed in the consuming application.
|
||||
* If it is not installed, or there is no active context at request time,
|
||||
* propagation silently no-ops.
|
||||
*
|
||||
* @example Enable with defaults
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* tracePropagation: { enabled: true },
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @see https://www.w3.org/TR/trace-context/
|
||||
* @see https://opentelemetry.io/docs/concepts/context-propagation/
|
||||
* @see https://supabase.com/docs/guides/telemetry/client-side-tracing
|
||||
*/
|
||||
interface TracePropagationOptions {
|
||||
/**
|
||||
* Enable trace propagation. Disabled by default.
|
||||
*
|
||||
* When enabled, automatically detects and propagates active trace context
|
||||
* from the OpenTelemetry API to outgoing Supabase requests. Trace context
|
||||
* is only propagated to Supabase domains (`*.supabase.co`, `*.supabase.in`,
|
||||
* `localhost`) for security — third-party hosts never receive trace headers.
|
||||
*
|
||||
* @default false
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* tracePropagation: { enabled: true },
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
enabled?: boolean;
|
||||
/**
|
||||
* Respect upstream sampling decisions.
|
||||
*
|
||||
* When true (the default), trace context is not propagated if the upstream
|
||||
* trace indicates non-sampling (sampled flag = `0` in the `traceparent`
|
||||
* header). This avoids overhead when traces are being recorded but dropped.
|
||||
*
|
||||
* Set to `false` to always propagate, regardless of the sampling decision
|
||||
* — useful when you want every Supabase request tagged with a `trace_id`
|
||||
* for log correlation, even if the trace itself will not be exported.
|
||||
*
|
||||
* @default true
|
||||
*
|
||||
* @example Always propagate, ignore sampling
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* tracePropagation: { enabled: true, respectSamplingDecision: false },
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
respectSamplingDecision?: boolean;
|
||||
}
|
||||
type SupabaseClientOptions<SchemaName> = {
|
||||
/**
|
||||
* The Postgres schema which your tables belong to. Must be on the list of exposed schemas in Supabase. Defaults to `public`.
|
||||
*/
|
||||
db?: {
|
||||
schema?: SchemaName;
|
||||
/**
|
||||
* Optional timeout in milliseconds for PostgREST requests.
|
||||
* When set, requests will automatically abort after this duration to prevent indefinite hangs.
|
||||
*
|
||||
* @example With timeout
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* db: { timeout: 30000 } // 30 second timeout
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
timeout?: number;
|
||||
/**
|
||||
* Maximum URL length in characters before warnings/errors are triggered.
|
||||
* Defaults to 8000 characters. Used to provide helpful hints when URLs
|
||||
* exceed server limits.
|
||||
*
|
||||
* @example With custom URL length limit
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* db: { urlLengthLimit: 10000 } // Custom limit
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
urlLengthLimit?: number;
|
||||
};
|
||||
auth?: {
|
||||
/**
|
||||
* Automatically refreshes the token for logged-in users. Defaults to true.
|
||||
*/
|
||||
autoRefreshToken?: boolean;
|
||||
/**
|
||||
* Optional key name used for storing tokens in local storage.
|
||||
*/
|
||||
storageKey?: string;
|
||||
/**
|
||||
* Whether to persist a logged-in session to storage. Defaults to true.
|
||||
*/
|
||||
persistSession?: boolean;
|
||||
/**
|
||||
* Detect a session from the URL. Used for OAuth login callbacks. Defaults to true.
|
||||
*
|
||||
* Can be set to a function to provide custom logic for determining if a URL contains
|
||||
* a Supabase auth callback. The function receives the current URL and parsed parameters,
|
||||
* and should return true if the URL should be processed as a Supabase auth callback.
|
||||
*
|
||||
* This is useful when your app uses other OAuth providers (e.g., Facebook Login) that
|
||||
* also return access_token in the URL fragment, which would otherwise be incorrectly
|
||||
* intercepted by Supabase Auth.
|
||||
*
|
||||
* @example With custom detection logic
|
||||
* ```ts
|
||||
* detectSessionInUrl: (url, params) => {
|
||||
* // Ignore Facebook OAuth redirects
|
||||
* if (url.pathname === '/facebook/redirect') return false
|
||||
* // Use default detection for other URLs
|
||||
* return Boolean(params.access_token || params.error_description)
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
detectSessionInUrl?: boolean | ((url: URL, params: {
|
||||
[parameter: string]: string;
|
||||
}) => boolean);
|
||||
/**
|
||||
* A storage provider. Used to store the logged-in session.
|
||||
*/
|
||||
storage?: SupabaseAuthClientOptions['storage'];
|
||||
/**
|
||||
* A storage provider to store the user profile separately from the session.
|
||||
* Useful when you need to store the session information in cookies,
|
||||
* without bloating the data with the redundant user object.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
userStorage?: SupabaseAuthClientOptions['userStorage'];
|
||||
/**
|
||||
* OAuth flow to use - defaults to implicit flow. PKCE is recommended for mobile and server-side applications.
|
||||
*/
|
||||
flowType?: SupabaseAuthClientOptions['flowType'];
|
||||
/**
|
||||
* If debug messages for authentication client are emitted. Can be used to inspect the behavior of the library.
|
||||
*/
|
||||
debug?: SupabaseAuthClientOptions['debug'];
|
||||
/**
|
||||
* Provide your own locking mechanism based on the environment. By default
|
||||
* the auth client coordinates refreshes itself and the server resolves
|
||||
* cross-tab races. Passing a custom `lock` opts into a legacy path that
|
||||
* wraps every auth operation in your supplied lock.
|
||||
*
|
||||
* @deprecated Custom locks still work in v2.x for backwards compatibility.
|
||||
* The legacy lock path will be removed in v3 — drop this option from your
|
||||
* `createClient` options before upgrading.
|
||||
*/
|
||||
lock?: SupabaseAuthClientOptions['lock'];
|
||||
/**
|
||||
* If there is an error with the query, throwOnError will reject the promise by
|
||||
* throwing the error instead of returning it as part of a successful response.
|
||||
*/
|
||||
throwOnError?: SupabaseAuthClientOptions['throwOnError'];
|
||||
/**
|
||||
* Opt-in flags for experimental features. These APIs may change without
|
||||
* notice and are disabled by default.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
experimental?: SupabaseAuthClientOptions['experimental'];
|
||||
/**
|
||||
* Maximum time in milliseconds to wait for acquiring the custom lock
|
||||
* supplied via `lock`. Only consulted when a custom `lock` is passed.
|
||||
*
|
||||
* @default 5000
|
||||
*
|
||||
* @deprecated Only used by the legacy lock path. Will be removed in v3
|
||||
* along with the `lock` option.
|
||||
*/
|
||||
lockAcquireTimeout?: SupabaseAuthClientOptions['lockAcquireTimeout'];
|
||||
/**
|
||||
* If true, skips automatic initialization in the auth client constructor.
|
||||
* Useful for SSR contexts where initialization timing must be controlled to
|
||||
* prevent race conditions with HTTP response generation.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
skipAutoInitialize?: SupabaseAuthClientOptions['skipAutoInitialize'];
|
||||
};
|
||||
/**
|
||||
* Options passed to the realtime-js instance
|
||||
*/
|
||||
realtime?: RealtimeClientOptions;
|
||||
storage?: StorageClientOptions;
|
||||
global?: {
|
||||
/**
|
||||
* A custom `fetch` implementation.
|
||||
*/
|
||||
fetch?: Fetch;
|
||||
/**
|
||||
* Optional headers for initializing the client.
|
||||
*/
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
/**
|
||||
* Optional function for using a third-party authentication system with
|
||||
* Supabase. The function should return an access token or ID token (JWT) by
|
||||
* obtaining it from the third-party auth SDK. Note that this
|
||||
* function may be called concurrently and many times. Use memoization and
|
||||
* locking techniques if this is not supported by the SDKs.
|
||||
*
|
||||
* When set, the `auth` namespace of the Supabase client cannot be used.
|
||||
* Create another client if you wish to use Supabase Auth and third-party
|
||||
* authentications concurrently in the same application.
|
||||
*/
|
||||
accessToken?: () => Promise<string | null>;
|
||||
/**
|
||||
* Enable OpenTelemetry / W3C trace context propagation to Supabase services.
|
||||
*
|
||||
* Disabled by default. Pass `true` for the common case (auto-detect an
|
||||
* active OpenTelemetry context and inject `traceparent` / `tracestate` /
|
||||
* `baggage` headers) or an object for fine-grained control.
|
||||
*
|
||||
* Requires `@opentelemetry/api` to be installed in your application; if
|
||||
* not present, the SDK silently no-ops. Trace headers are only attached
|
||||
* to requests targeting Supabase domains, so third-party hosts called
|
||||
* through a custom `fetch` are never tagged.
|
||||
*
|
||||
* The resulting `trace_id` appears in Supabase logs (API Gateway, Edge
|
||||
* Functions), letting you correlate client-side spans with server-side
|
||||
* log entries — including logs forwarded via Log Drains.
|
||||
*
|
||||
* @example Shorthand — opt in with defaults
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient(url, key, { tracePropagation: true })
|
||||
* ```
|
||||
*
|
||||
* @example With an active OpenTelemetry span
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import { trace } from '@opentelemetry/api'
|
||||
*
|
||||
* const supabase = createClient(url, key, { tracePropagation: true })
|
||||
* const tracer = trace.getTracer('my-app')
|
||||
*
|
||||
* await tracer.startActiveSpan('fetch-users', async (span) => {
|
||||
* // Request carries the active trace context.
|
||||
* const { data, error } = await supabase.from('users').select('*')
|
||||
* span.end()
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @example Advanced — always propagate, even for non-sampled traces
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* tracePropagation: { enabled: true, respectSamplingDecision: false },
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @see https://supabase.com/docs/guides/telemetry/client-side-tracing
|
||||
* @see https://www.w3.org/TR/trace-context/
|
||||
*/
|
||||
tracePropagation?: TracePropagationOptions | boolean;
|
||||
};
|
||||
/**
|
||||
* Helper types for query results.
|
||||
*/
|
||||
type QueryResult<T> = T extends PromiseLike<infer U> ? U : never;
|
||||
type QueryData<T> = T extends PromiseLike<{
|
||||
data: infer U;
|
||||
}> ? Exclude<U, null> : never;
|
||||
type QueryError = PostgrestError$1;
|
||||
/**
|
||||
* Strips internal Supabase metadata from Database types.
|
||||
* Useful for libraries defining generic constraints on Database types.
|
||||
*
|
||||
* @example Stripping internal Supabase metadata
|
||||
* ```typescript
|
||||
* type CleanDB = DatabaseWithoutInternals<Database>
|
||||
* ```
|
||||
*/
|
||||
type DatabaseWithoutInternals<DB> = Omit<DB, '__InternalSupabase'>;
|
||||
//#endregion
|
||||
//#region src/lib/helpers.d.ts
|
||||
type ResolvedSupabaseClientOptions<SchemaName> = Omit<Required<SupabaseClientOptions<SchemaName>>, 'tracePropagation'> & {
|
||||
tracePropagation: TracePropagationOptions;
|
||||
};
|
||||
//#endregion
|
||||
//#region src/lib/SupabaseAuthClient.d.ts
|
||||
declare class SupabaseAuthClient extends AuthClient {
|
||||
constructor(options: SupabaseAuthClientOptions);
|
||||
}
|
||||
//#endregion
|
||||
//#region src/lib/rest/types/common/rpc.d.ts
|
||||
type IsMatchingArgs<FnArgs extends GenericFunction['Args'], PassedArgs extends GenericFunction['Args']> = [FnArgs] extends [Record<PropertyKey, never>] ? PassedArgs extends Record<PropertyKey, never> ? true : false : keyof PassedArgs extends keyof FnArgs ? PassedArgs extends FnArgs ? true : false : false;
|
||||
type MatchingFunctionArgs<Fn$1 extends GenericFunction, Args extends GenericFunction['Args']> = Fn$1 extends {
|
||||
Args: infer A extends GenericFunction['Args'];
|
||||
} ? IsMatchingArgs<A, Args> extends true ? Fn$1 : never : false;
|
||||
type FindMatchingFunctionByArgs<FnUnion, Args extends GenericFunction['Args']> = FnUnion extends infer Fn extends GenericFunction ? MatchingFunctionArgs<Fn, Args> : false;
|
||||
type TablesAndViews<Schema extends GenericSchema> = Schema['Tables'] & Exclude<Schema['Views'], ''>;
|
||||
type UnionToIntersection<U$1> = (U$1 extends any ? (k: U$1) => void : never) extends ((k: infer I) => void) ? I : never;
|
||||
type LastOf<T> = UnionToIntersection<T extends any ? () => T : never> extends (() => infer R) ? R : never;
|
||||
type IsAny<T> = 0 extends 1 & T ? true : false;
|
||||
type ExactMatch<T, S> = [T] extends [S] ? ([S] extends [T] ? true : false) : false;
|
||||
type ExtractExactFunction<Fns, Args> = Fns extends infer F ? F extends GenericFunction ? ExactMatch<F['Args'], Args> extends true ? F : never : never : never;
|
||||
type IsNever<T> = [T] extends [never] ? true : false;
|
||||
type RpcFunctionNotFound<FnName> = {
|
||||
Row: any;
|
||||
Result: {
|
||||
error: true;
|
||||
} & "Couldn't infer function definition matching provided arguments";
|
||||
RelationName: FnName;
|
||||
Relationships: null;
|
||||
};
|
||||
type CrossSchemaError<TableRef extends string> = {
|
||||
error: true;
|
||||
} & `Function returns SETOF from a different schema ('${TableRef}'). Use .overrideTypes<YourReturnType>() to specify the return type explicitly.`;
|
||||
type GetRpcFunctionFilterBuilderByArgs<Schema extends GenericSchema, FnName extends string & keyof Schema['Functions'], Args> = {
|
||||
0: Schema['Functions'][FnName];
|
||||
1: IsAny<Schema> extends true ? any : IsNever<Args> extends true ? IsNever<ExtractExactFunction<Schema['Functions'][FnName], Args>> extends true ? LastOf<Schema['Functions'][FnName]> : ExtractExactFunction<Schema['Functions'][FnName], Args> : Args extends Record<PropertyKey, never> ? LastOf<Schema['Functions'][FnName]> : Args extends GenericFunction['Args'] ? IsNever<LastOf<FindMatchingFunctionByArgs<Schema['Functions'][FnName], Args>>> extends true ? LastOf<Schema['Functions'][FnName]> : LastOf<FindMatchingFunctionByArgs<Schema['Functions'][FnName], Args>> : ExtractExactFunction<Schema['Functions'][FnName], Args> extends GenericFunction ? ExtractExactFunction<Schema['Functions'][FnName], Args> : any;
|
||||
}[1] extends infer Fn ? IsAny<Fn> extends true ? {
|
||||
Row: any;
|
||||
Result: any;
|
||||
RelationName: FnName;
|
||||
Relationships: null;
|
||||
} : Fn extends GenericFunction ? {
|
||||
Row: Fn['SetofOptions'] extends GenericSetofOption ? Fn['SetofOptions']['to'] extends keyof TablesAndViews<Schema> ? TablesAndViews<Schema>[Fn['SetofOptions']['to']]['Row'] : Fn['Returns'] extends any[] ? Fn['Returns'][number] extends Record<string, unknown> ? Fn['Returns'][number] : CrossSchemaError<Fn['SetofOptions']['to'] & string> : Fn['Returns'] extends Record<string, unknown> ? Fn['Returns'] : CrossSchemaError<Fn['SetofOptions']['to'] & string> : Fn['Returns'] extends any[] ? Fn['Returns'][number] extends Record<string, unknown> ? Fn['Returns'][number] : never : Fn['Returns'] extends Record<string, unknown> ? Fn['Returns'] : never;
|
||||
Result: Fn['SetofOptions'] extends GenericSetofOption ? Fn['SetofOptions']['isSetofReturn'] extends true ? Fn['SetofOptions']['isOneToOne'] extends true ? Fn['Returns'][] : Fn['Returns'] : Fn['Returns'] : Fn['Returns'];
|
||||
RelationName: Fn['SetofOptions'] extends GenericSetofOption ? Fn['SetofOptions']['to'] : FnName;
|
||||
Relationships: Fn['SetofOptions'] extends GenericSetofOption ? Fn['SetofOptions']['to'] extends keyof Schema['Tables'] ? Schema['Tables'][Fn['SetofOptions']['to']]['Relationships'] : Fn['SetofOptions']['to'] extends keyof Schema['Views'] ? Schema['Views'][Fn['SetofOptions']['to']]['Relationships'] : null : null;
|
||||
} : Fn extends false ? RpcFunctionNotFound<FnName> : RpcFunctionNotFound<FnName> : RpcFunctionNotFound<FnName>;
|
||||
//#endregion
|
||||
//#region src/SupabaseClient.d.ts
|
||||
/**
|
||||
* Supabase Client.
|
||||
*
|
||||
* An isomorphic Javascript client for interacting with Postgres.
|
||||
*/
|
||||
declare class SupabaseClient<Database = any, SchemaNameOrClientOptions extends (string & keyof Omit<Database, '__InternalSupabase'>) | {
|
||||
PostgrestVersion: string;
|
||||
} = ('public' extends keyof Omit<Database, '__InternalSupabase'> ? 'public' : string & keyof Omit<Database, '__InternalSupabase'>), SchemaName extends string & keyof Omit<Database, '__InternalSupabase'> = (SchemaNameOrClientOptions extends string & keyof Omit<Database, '__InternalSupabase'> ? SchemaNameOrClientOptions : 'public' extends keyof Omit<Database, '__InternalSupabase'> ? 'public' : string & keyof Omit<Omit<Database, '__InternalSupabase'>, '__InternalSupabase'>), Schema extends (Omit<Database, '__InternalSupabase'>[SchemaName] extends GenericSchema ? Omit<Database, '__InternalSupabase'>[SchemaName] : never) = (Omit<Database, '__InternalSupabase'>[SchemaName] extends GenericSchema ? Omit<Database, '__InternalSupabase'>[SchemaName] : never), ClientOptions extends {
|
||||
PostgrestVersion: string;
|
||||
} = (SchemaNameOrClientOptions extends string & keyof Omit<Database, '__InternalSupabase'> ? Database extends {
|
||||
__InternalSupabase: {
|
||||
PostgrestVersion: string;
|
||||
};
|
||||
} ? Database['__InternalSupabase'] : {
|
||||
PostgrestVersion: '12';
|
||||
} : SchemaNameOrClientOptions extends {
|
||||
PostgrestVersion: string;
|
||||
} ? SchemaNameOrClientOptions : never)> {
|
||||
protected supabaseUrl: string;
|
||||
protected supabaseKey: string;
|
||||
/**
|
||||
* Supabase Auth allows you to create and manage user sessions for access to data that is secured by access policies.
|
||||
*/
|
||||
auth: SupabaseAuthClient;
|
||||
realtime: RealtimeClient;
|
||||
/**
|
||||
* Supabase Storage allows you to manage user-generated content, such as photos or videos.
|
||||
*/
|
||||
storage: StorageClient;
|
||||
protected realtimeUrl: URL;
|
||||
protected authUrl: URL;
|
||||
protected storageUrl: URL;
|
||||
protected functionsUrl: URL;
|
||||
protected rest: PostgrestClient<Database, ClientOptions, SchemaName>;
|
||||
protected storageKey: string;
|
||||
protected fetch?: Fetch;
|
||||
protected functionsFetch?: Fetch;
|
||||
protected changedAccessToken?: string;
|
||||
protected accessToken?: () => Promise<string | null>;
|
||||
protected headers: Record<string, string>;
|
||||
protected settings?: ResolvedSupabaseClientOptions<SchemaName>;
|
||||
/**
|
||||
* Create a new client for use in the browser.
|
||||
*
|
||||
* @category Initializing
|
||||
*
|
||||
* @param supabaseUrl The unique Supabase URL which is supplied when you create a new project in your project dashboard.
|
||||
* @param supabaseKey The unique Supabase Key which is supplied when you create a new project in your project dashboard.
|
||||
* @param options Optional configuration for the client:
|
||||
* - `db.schema` — You can switch in between schemas. The schema needs to be on the list of exposed schemas inside Supabase.
|
||||
* - `auth.autoRefreshToken` — Set to `true` if you want to automatically refresh the token before expiring.
|
||||
* - `auth.persistSession` — Set to `true` if you want to automatically save the user session into local storage.
|
||||
* - `auth.detectSessionInUrl` — Set to `true` if you want to automatically detect OAuth grants in the URL and sign in the user.
|
||||
* - `realtime` — Options passed along to the realtime-js constructor.
|
||||
* - `storage` — Options passed along to the storage-js constructor.
|
||||
* - `global.fetch` — A custom fetch implementation.
|
||||
* - `global.headers` — Any additional headers to send with each network request.
|
||||
*
|
||||
* @example Creating a client
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* // Create a single supabase client for interacting with your database
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
* ```
|
||||
*
|
||||
* @example With a custom domain
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* // Use a custom domain as the supabase URL
|
||||
* const supabase = createClient('https://my-custom-domain.com', 'your-publishable-key')
|
||||
* ```
|
||||
*
|
||||
* @example With additional parameters
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const options = {
|
||||
* db: {
|
||||
* schema: 'public',
|
||||
* },
|
||||
* auth: {
|
||||
* autoRefreshToken: true,
|
||||
* persistSession: true,
|
||||
* detectSessionInUrl: true
|
||||
* },
|
||||
* global: {
|
||||
* headers: { 'x-my-custom-header': 'my-app-name' },
|
||||
* },
|
||||
* }
|
||||
* const supabase = createClient("https://xyzcompany.supabase.co", "your-publishable-key", options)
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription With custom schemas
|
||||
* By default the API server points to the `public` schema. You can enable other database schemas within the Dashboard.
|
||||
* Go to [Settings > API > Exposed schemas](/dashboard/project/_/settings/api) and add the schema which you want to expose to the API.
|
||||
*
|
||||
* Note: each client connection can only access a single schema, so the code above can access the `other_schema` schema but cannot access the `public` schema.
|
||||
*
|
||||
* @example With custom schemas
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
* // Provide a custom schema. Defaults to "public".
|
||||
* db: { schema: 'other_schema' }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription Custom fetch implementation
|
||||
* `supabase-js` uses the runtime's global `fetch` to make HTTP requests,
|
||||
* but an alternative `fetch` implementation can be provided as an option.
|
||||
* This is useful in environments where the global `fetch` is unavailable or where you want to customize request behavior.
|
||||
*
|
||||
* @example Custom fetch implementation
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
* global: { fetch: fetch.bind(globalThis) }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription React Native options with AsyncStorage
|
||||
* For React Native we recommend using `AsyncStorage` as the storage implementation for Supabase Auth.
|
||||
*
|
||||
* @example React Native options with AsyncStorage
|
||||
* ```js
|
||||
* import 'react-native-url-polyfill/auto'
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
*
|
||||
* const supabase = createClient("https://xyzcompany.supabase.co", "your-publishable-key", {
|
||||
* auth: {
|
||||
* storage: AsyncStorage,
|
||||
* autoRefreshToken: true,
|
||||
* persistSession: true,
|
||||
* detectSessionInUrl: false,
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription React Native options with Expo SecureStore
|
||||
* If you wish to encrypt the user's session information, you can use `aes-js` and store the encryption key in Expo SecureStore.
|
||||
* The `aes-js` library, a reputable JavaScript-only implementation of the AES encryption algorithm in CTR mode.
|
||||
* A new 256-bit encryption key is generated using the `react-native-get-random-values` library.
|
||||
* This key is stored inside Expo's SecureStore, while the value is encrypted and placed inside AsyncStorage.
|
||||
*
|
||||
* Please make sure that:
|
||||
* - You keep the `expo-secure-store`, `aes-js` and `react-native-get-random-values` libraries up-to-date.
|
||||
* - Choose the correct [`SecureStoreOptions`](https://docs.expo.dev/versions/latest/sdk/securestore/#securestoreoptions) for your app's needs.
|
||||
* E.g. [`SecureStore.WHEN_UNLOCKED`](https://docs.expo.dev/versions/latest/sdk/securestore/#securestorewhen_unlocked) regulates when the data can be accessed.
|
||||
* - Carefully consider optimizations or other modifications to the above example, as those can lead to introducing subtle security vulnerabilities.
|
||||
*
|
||||
* @example React Native options with Expo SecureStore
|
||||
* ```ts
|
||||
* import 'react-native-url-polyfill/auto'
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
* import * as SecureStore from 'expo-secure-store';
|
||||
* import * as aesjs from 'aes-js';
|
||||
* import 'react-native-get-random-values';
|
||||
*
|
||||
* // As Expo's SecureStore does not support values larger than 2048
|
||||
* // bytes, an AES-256 key is generated and stored in SecureStore, while
|
||||
* // it is used to encrypt/decrypt values stored in AsyncStorage.
|
||||
* class LargeSecureStore {
|
||||
* private async _encrypt(key: string, value: string) {
|
||||
* const encryptionKey = crypto.getRandomValues(new Uint8Array(256 / 8));
|
||||
*
|
||||
* const cipher = new aesjs.ModeOfOperation.ctr(encryptionKey, new aesjs.Counter(1));
|
||||
* const encryptedBytes = cipher.encrypt(aesjs.utils.utf8.toBytes(value));
|
||||
*
|
||||
* await SecureStore.setItemAsync(key, aesjs.utils.hex.fromBytes(encryptionKey));
|
||||
*
|
||||
* return aesjs.utils.hex.fromBytes(encryptedBytes);
|
||||
* }
|
||||
*
|
||||
* private async _decrypt(key: string, value: string) {
|
||||
* const encryptionKeyHex = await SecureStore.getItemAsync(key);
|
||||
* if (!encryptionKeyHex) {
|
||||
* return encryptionKeyHex;
|
||||
* }
|
||||
*
|
||||
* const cipher = new aesjs.ModeOfOperation.ctr(aesjs.utils.hex.toBytes(encryptionKeyHex), new aesjs.Counter(1));
|
||||
* const decryptedBytes = cipher.decrypt(aesjs.utils.hex.toBytes(value));
|
||||
*
|
||||
* return aesjs.utils.utf8.fromBytes(decryptedBytes);
|
||||
* }
|
||||
*
|
||||
* async getItem(key: string) {
|
||||
* const encrypted = await AsyncStorage.getItem(key);
|
||||
* if (!encrypted) { return encrypted; }
|
||||
*
|
||||
* return await this._decrypt(key, encrypted);
|
||||
* }
|
||||
*
|
||||
* async removeItem(key: string) {
|
||||
* await AsyncStorage.removeItem(key);
|
||||
* await SecureStore.deleteItemAsync(key);
|
||||
* }
|
||||
*
|
||||
* async setItem(key: string, value: string) {
|
||||
* const encrypted = await this._encrypt(key, value);
|
||||
*
|
||||
* await AsyncStorage.setItem(key, encrypted);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* const supabase = createClient("https://xyzcompany.supabase.co", "your-publishable-key", {
|
||||
* auth: {
|
||||
* storage: new LargeSecureStore(),
|
||||
* autoRefreshToken: true,
|
||||
* persistSession: true,
|
||||
* detectSessionInUrl: false,
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example With a database query
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
*
|
||||
* const { data } = await supabase.from('profiles').select('*')
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription With OpenTelemetry tracing
|
||||
* Opt in to W3C trace context propagation so the `trace_id` from your
|
||||
* client-side spans is attached to Supabase requests and appears in API
|
||||
* Gateway and Edge Function logs. Requires `@opentelemetry/api` to be
|
||||
* installed in your application. See [Tracing with the JS SDK](https://supabase.com/docs/guides/telemetry/client-side-tracing).
|
||||
*
|
||||
* @example With OpenTelemetry tracing
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import { trace } from '@opentelemetry/api'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
* tracePropagation: true,
|
||||
* })
|
||||
*
|
||||
* const tracer = trace.getTracer('my-app')
|
||||
*
|
||||
* await tracer.startActiveSpan('fetch-users', async (span) => {
|
||||
* // Outgoing request carries the active trace context.
|
||||
* const { data, error } = await supabase.from('users').select('*')
|
||||
* span.end()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
constructor(supabaseUrl: string, supabaseKey: string, options?: SupabaseClientOptions<SchemaName>);
|
||||
/**
|
||||
* Supabase Functions allows you to deploy and invoke edge functions.
|
||||
*/
|
||||
get functions(): FunctionsClient;
|
||||
from<TableName extends string & keyof Schema['Tables'], Table extends Schema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder$1<ClientOptions, Schema, Table, TableName>;
|
||||
from<ViewName extends string & keyof Schema['Views'], View extends Schema['Views'][ViewName]>(relation: ViewName): PostgrestQueryBuilder$1<ClientOptions, Schema, View, ViewName>;
|
||||
/**
|
||||
* Select a schema to query or perform an function (rpc) call.
|
||||
*
|
||||
* The schema needs to be on the list of exposed schemas inside Supabase.
|
||||
*
|
||||
* @param schema - The schema to query
|
||||
*/
|
||||
schema<DynamicSchema extends string & keyof Omit<Database, '__InternalSupabase'>>(schema: DynamicSchema): PostgrestClient<Database, ClientOptions, DynamicSchema, Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any>;
|
||||
/**
|
||||
* Perform a function call.
|
||||
*
|
||||
* @param fn - The function name to call
|
||||
* @param args - The arguments to pass to the function call
|
||||
* @param options - Named parameters
|
||||
* @param options.head - When set to `true`, `data` will not be returned.
|
||||
* Useful if you only need the count.
|
||||
* @param options.get - When set to `true`, the function will be called with
|
||||
* read-only access mode.
|
||||
* @param options.count - Count algorithm to use to count rows returned by the
|
||||
* function. Only applicable for [set-returning
|
||||
* functions](https://www.postgresql.org/docs/current/functions-srf.html).
|
||||
*
|
||||
* `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the
|
||||
* hood.
|
||||
*
|
||||
* `"planned"`: Approximated but fast count algorithm. Uses the Postgres
|
||||
* statistics under the hood.
|
||||
*
|
||||
* `"estimated"`: Uses exact count for low numbers and planned count for high
|
||||
* numbers.
|
||||
*/
|
||||
rpc<FnName extends string & keyof Schema['Functions'], Args extends Schema['Functions'][FnName]['Args'] = never, FilterBuilder extends GetRpcFunctionFilterBuilderByArgs<Schema, FnName, Args> = GetRpcFunctionFilterBuilderByArgs<Schema, FnName, Args>>(fn: FnName, args?: Args, options?: {
|
||||
head?: boolean;
|
||||
get?: boolean;
|
||||
count?: 'exact' | 'planned' | 'estimated';
|
||||
}): PostgrestFilterBuilder$1<ClientOptions, Schema, FilterBuilder['Row'], FilterBuilder['Result'], FilterBuilder['RelationName'], FilterBuilder['Relationships'], 'RPC'>;
|
||||
/**
|
||||
* Creates a Realtime channel with Broadcast, Presence, and Postgres Changes.
|
||||
*
|
||||
* @param {string} name - The name of the Realtime channel.
|
||||
* @param {Object} opts - The options to pass to the Realtime channel.
|
||||
*
|
||||
* @category Realtime
|
||||
*/
|
||||
channel(name: string, opts?: RealtimeChannelOptions): RealtimeChannel;
|
||||
/**
|
||||
* Returns all Realtime channels.
|
||||
*
|
||||
* @category Realtime
|
||||
*
|
||||
* @example Get all channels
|
||||
* ```js
|
||||
* const channels = supabase.getChannels()
|
||||
* ```
|
||||
*/
|
||||
getChannels(): RealtimeChannel[];
|
||||
/**
|
||||
* Unsubscribes and removes Realtime channel from Realtime client.
|
||||
*
|
||||
* @param {RealtimeChannel} channel - The name of the Realtime channel.
|
||||
*
|
||||
*
|
||||
* @category Realtime
|
||||
*
|
||||
* @remarks
|
||||
* - Removing a channel is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
|
||||
*
|
||||
* @example Removes a channel
|
||||
* ```js
|
||||
* supabase.removeChannel(myChannel)
|
||||
* ```
|
||||
*/
|
||||
removeChannel(channel: RealtimeChannel): Promise<RealtimeRemoveChannelResponse>;
|
||||
/**
|
||||
* Unsubscribes and removes all Realtime channels from Realtime client.
|
||||
*
|
||||
* @category Realtime
|
||||
*
|
||||
* @remarks
|
||||
* - Removing channels is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
|
||||
*
|
||||
* @example Remove all channels
|
||||
* ```js
|
||||
* supabase.removeAllChannels()
|
||||
* ```
|
||||
*/
|
||||
removeAllChannels(): Promise<RealtimeRemoveChannelResponse[]>;
|
||||
/**
|
||||
* The raw session token — the custom `accessToken` result or the signed-in user's JWT —
|
||||
* or `null` when there is no session. Unlike {@link _getAccessToken} it does not fall back
|
||||
* to `supabaseKey`, so callers can distinguish "no session" from "has session".
|
||||
*/
|
||||
private _getSessionToken;
|
||||
private _getAccessToken;
|
||||
private _initSupabaseAuthClient;
|
||||
private _initRealtimeClient;
|
||||
private _listenForAuthEvents;
|
||||
private _handleTokenChanged;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/index.d.ts
|
||||
/**
|
||||
* Creates a new Supabase Client.
|
||||
*
|
||||
* @example Creating a Supabase client
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
* const { data, error } = await supabase.from('profiles').select('*')
|
||||
* ```
|
||||
*/
|
||||
declare const createClient: <Database = any, SchemaNameOrClientOptions extends (string & keyof Omit<Database, "__InternalSupabase">) | {
|
||||
PostgrestVersion: string;
|
||||
} = ("public" extends keyof Omit<Database, "__InternalSupabase"> ? "public" : string & keyof Omit<Database, "__InternalSupabase">), SchemaName extends string & keyof Omit<Database, "__InternalSupabase"> = (SchemaNameOrClientOptions extends string & keyof Omit<Database, "__InternalSupabase"> ? SchemaNameOrClientOptions : "public" extends keyof Omit<Database, "__InternalSupabase"> ? "public" : string & keyof Omit<Omit<Database, "__InternalSupabase">, "__InternalSupabase">)>(supabaseUrl: string, supabaseKey: string, options?: SupabaseClientOptions<SchemaName>) => SupabaseClient<Database, SchemaNameOrClientOptions, SchemaName>;
|
||||
//#endregion
|
||||
export { type AuthSession, type AuthUser, type DatabaseWithoutInternals, type FunctionInvokeOptions, FunctionRegion, FunctionsError, FunctionsFetchError, FunctionsHttpError, FunctionsRelayError, type PostgrestBuilder, PostgrestError, type PostgrestFilterBuilder, type PostgrestMaybeSingleResponse, type PostgrestQueryBuilder, type PostgrestResponse, type PostgrestSingleResponse, type PostgrestTransformBuilder, type QueryData, type QueryError, type QueryResult, StorageApiError, SupabaseClient, type SupabaseClientOptions, type TracePropagationOptions, createClient };
|
||||
//# sourceMappingURL=index.d.mts.map
|
||||
+1
File diff suppressed because one or more lines are too long
+927
@@ -0,0 +1,927 @@
|
||||
import { FunctionRegion, FunctionsClient, FunctionsError, FunctionsFetchError, FunctionsHttpError, FunctionsRelayError } from "@supabase/functions-js";
|
||||
import { PostgrestClient, PostgrestError } from "@supabase/postgrest-js";
|
||||
import { RealtimeClient } from "@supabase/realtime-js";
|
||||
import { StorageApiError, StorageClient } from "@supabase/storage-js";
|
||||
import { AuthClient } from "@supabase/auth-js";
|
||||
|
||||
export * from "@supabase/realtime-js"
|
||||
|
||||
export * from "@supabase/auth-js"
|
||||
|
||||
//#region src/lib/version.ts
|
||||
const version = "2.110.8";
|
||||
|
||||
//#endregion
|
||||
//#region src/lib/constants.ts
|
||||
let JS_ENV = "";
|
||||
let JS_RUNTIME_VERSION;
|
||||
if (typeof Deno !== "undefined") {
|
||||
var _Deno$version;
|
||||
JS_ENV = "deno";
|
||||
JS_RUNTIME_VERSION = (_Deno$version = Deno.version) === null || _Deno$version === void 0 ? void 0 : _Deno$version.deno;
|
||||
} else if (typeof document !== "undefined") JS_ENV = "web";
|
||||
else if (typeof navigator !== "undefined" && navigator.product === "ReactNative") JS_ENV = "react-native";
|
||||
else {
|
||||
var _process$version;
|
||||
JS_ENV = "node";
|
||||
const _process = globalThis["process"];
|
||||
JS_RUNTIME_VERSION = _process === null || _process === void 0 || (_process$version = _process["version"]) === null || _process$version === void 0 ? void 0 : _process$version.replace(/^v/, "");
|
||||
}
|
||||
const _runtimeMeta = [`runtime=${JS_ENV}`];
|
||||
if (JS_RUNTIME_VERSION) _runtimeMeta.push(`runtime-version=${JS_RUNTIME_VERSION}`);
|
||||
const DEFAULT_HEADERS = { "X-Client-Info": `supabase-js/${version}; ${_runtimeMeta.join("; ")}` };
|
||||
const DEFAULT_GLOBAL_OPTIONS = { headers: DEFAULT_HEADERS };
|
||||
const DEFAULT_DB_OPTIONS = { schema: "public" };
|
||||
const DEFAULT_AUTH_OPTIONS = {
|
||||
autoRefreshToken: true,
|
||||
persistSession: true,
|
||||
detectSessionInUrl: true,
|
||||
flowType: "implicit"
|
||||
};
|
||||
const DEFAULT_REALTIME_OPTIONS = {};
|
||||
const DEFAULT_TRACE_PROPAGATION_OPTIONS = {
|
||||
enabled: false,
|
||||
respectSamplingDecision: true
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region ../../../node_modules/.pnpm/tslib@2.8.1/node_modules/tslib/tslib.es6.mjs
|
||||
function __awaiter(thisArg, _arguments, P, generator) {
|
||||
function adopt(value) {
|
||||
return value instanceof P ? value : new P(function(resolve) {
|
||||
resolve(value);
|
||||
});
|
||||
}
|
||||
return new (P || (P = Promise))(function(resolve, reject) {
|
||||
function fulfilled(value) {
|
||||
try {
|
||||
step(generator.next(value));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
function rejected(value) {
|
||||
try {
|
||||
step(generator["throw"](value));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
function step(result) {
|
||||
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||||
}
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region ../../shared/tracing/dist/module/extract.js
|
||||
let otelModulePromise = null;
|
||||
const OTEL_PKG = "@opentelemetry/api";
|
||||
function loadOtel() {
|
||||
if (otelModulePromise === null) otelModulePromise = import(/* webpackIgnore: true */ /* turbopackIgnore: true */ /* @vite-ignore */ OTEL_PKG).catch(() => null);
|
||||
return otelModulePromise;
|
||||
}
|
||||
/**
|
||||
* Extract trace context from the OpenTelemetry API.
|
||||
*
|
||||
* Returns null if `@opentelemetry/api` is not installed or there is no active
|
||||
* trace context. The dynamic import is cached after the first call.
|
||||
*
|
||||
* @returns Trace context with traceparent, tracestate, and baggage headers, or null if unavailable
|
||||
*/
|
||||
function extractTraceContext() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const otel = yield loadOtel();
|
||||
if (!otel || !otel.propagation || !otel.context) return null;
|
||||
const carrier = {};
|
||||
otel.propagation.inject(otel.context.active(), carrier);
|
||||
const traceparent = carrier["traceparent"];
|
||||
if (!traceparent) return null;
|
||||
return {
|
||||
traceparent,
|
||||
tracestate: carrier["tracestate"],
|
||||
baggage: carrier["baggage"]
|
||||
};
|
||||
} catch (_a) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region ../../shared/tracing/dist/module/parse.js
|
||||
/**
|
||||
* Parse W3C traceparent header according to the specification.
|
||||
*
|
||||
* The traceparent header format is: version-traceid-parentid-traceflags
|
||||
* - version: 2 hex digits (currently always "00")
|
||||
* - traceid: 32 hex digits (128-bit trace identifier)
|
||||
* - parentid: 16 hex digits (64-bit span/parent identifier)
|
||||
* - traceflags: 2 hex digits (8-bit flags, bit 0 is sampled flag)
|
||||
*
|
||||
* @param traceparent - The traceparent header value
|
||||
* @returns Parsed traceparent object, or null if invalid format
|
||||
*
|
||||
* @see https://www.w3.org/TR/trace-context/#traceparent-header
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const parsed = parseTraceParent('00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01')
|
||||
*
|
||||
* console.log(parsed)
|
||||
* // {
|
||||
* // version: '00',
|
||||
* // traceId: '0af7651916cd43dd8448eb211c80319c',
|
||||
* // parentId: 'b7ad6b7169203331',
|
||||
* // traceFlags: '01',
|
||||
* // isSampled: true
|
||||
* // }
|
||||
* ```
|
||||
*/
|
||||
function parseTraceParent(traceparent) {
|
||||
if (!traceparent || typeof traceparent !== "string") return null;
|
||||
const parts = traceparent.split("-");
|
||||
if (parts.length !== 4) return null;
|
||||
const [version$1, traceId, parentId, traceFlags] = parts;
|
||||
if (version$1.length !== 2 || traceId.length !== 32 || parentId.length !== 16 || traceFlags.length !== 2) return null;
|
||||
const hexRegex = /^[0-9a-f]+$/i;
|
||||
if (!hexRegex.test(version$1) || !hexRegex.test(traceId) || !hexRegex.test(parentId) || !hexRegex.test(traceFlags)) return null;
|
||||
if (traceId === "00000000000000000000000000000000" || parentId === "0000000000000000") return null;
|
||||
return {
|
||||
version: version$1,
|
||||
traceId,
|
||||
parentId,
|
||||
traceFlags,
|
||||
isSampled: (parseInt(traceFlags, 16) & 1) === 1
|
||||
};
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region ../../shared/tracing/dist/module/validate.js
|
||||
/**
|
||||
* Check if trace context should be propagated to the target URL.
|
||||
*
|
||||
* This function checks if the target URL matches any of the configured
|
||||
* propagation targets. Targets can be:
|
||||
* - String: Exact hostname match or wildcard domain (*.example.com)
|
||||
* - RegExp: Pattern matching hostname
|
||||
* - Function: Custom logic to determine if URL should receive trace context
|
||||
*
|
||||
* @param targetUrl - The URL to check
|
||||
* @param targets - Array of propagation targets
|
||||
* @returns True if trace context should be propagated, false otherwise
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const targets = [
|
||||
* 'myproject.supabase.co', // Exact match
|
||||
* '*.supabase.co', // Wildcard domain
|
||||
* /.*\.supabase\.co$/, // Regex pattern
|
||||
* (url) => url.hostname === 'localhost' // Custom function
|
||||
* ]
|
||||
*
|
||||
* shouldPropagateToTarget('https://myproject.supabase.co/rest/v1/table', targets)
|
||||
* // true
|
||||
*
|
||||
* shouldPropagateToTarget('https://evil.com/api', targets)
|
||||
* // false
|
||||
* ```
|
||||
*/
|
||||
function shouldPropagateToTarget(targetUrl, targets) {
|
||||
if (!targetUrl || !targets || targets.length === 0) return false;
|
||||
let url;
|
||||
if (targetUrl instanceof URL) url = targetUrl;
|
||||
else try {
|
||||
url = new URL(targetUrl);
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
for (const target of targets) try {
|
||||
if (typeof target === "string") {
|
||||
if (matchStringTarget(url.hostname, target)) return true;
|
||||
} else if (target instanceof RegExp) {
|
||||
if (target.test(url.hostname)) return true;
|
||||
} else if (typeof target === "function") {
|
||||
if (target(url)) return true;
|
||||
}
|
||||
} catch (error) {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Match hostname against string target (exact match or wildcard)
|
||||
*
|
||||
* @param hostname - The hostname to check
|
||||
* @param target - The target pattern (exact or wildcard)
|
||||
* @returns True if hostname matches target
|
||||
*/
|
||||
function matchStringTarget(hostname, target) {
|
||||
if (target === hostname) return true;
|
||||
if (target.startsWith("*.")) {
|
||||
const domain = target.slice(2);
|
||||
if (hostname.endsWith(domain)) {
|
||||
if (hostname === domain || hostname.endsWith("." + domain)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region ../../shared/tracing/dist/module/defaults.js
|
||||
/**
|
||||
* Generate default propagation targets based on the Supabase project URL.
|
||||
*
|
||||
* By default, trace context is only propagated to Supabase domains for
|
||||
* security. This prevents leaking trace context to potentially malicious
|
||||
* third-party services.
|
||||
*
|
||||
* Wildcard strings (e.g. `*.supabase.co`) are matched with linear string
|
||||
* operations rather than regex, avoiding ReDoS risk.
|
||||
*
|
||||
* @param supabaseUrl - The Supabase project URL
|
||||
* @returns Array of default propagation targets
|
||||
*/
|
||||
function getDefaultPropagationTargets(supabaseUrl) {
|
||||
const targets = [];
|
||||
try {
|
||||
const url = new URL(supabaseUrl);
|
||||
targets.push(url.hostname);
|
||||
} catch (error) {}
|
||||
targets.push("*.supabase.co", "*.supabase.in");
|
||||
targets.push("localhost", "127.0.0.1", "[::1]");
|
||||
return targets;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region \0@oxc-project+runtime@0.103.0/helpers/typeof.js
|
||||
function _typeof(o) {
|
||||
"@babel/helpers - typeof";
|
||||
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
|
||||
return typeof o$1;
|
||||
} : function(o$1) {
|
||||
return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
|
||||
}, _typeof(o);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region \0@oxc-project+runtime@0.103.0/helpers/toPrimitive.js
|
||||
function toPrimitive(t, r) {
|
||||
if ("object" != _typeof(t) || !t) return t;
|
||||
var e = t[Symbol.toPrimitive];
|
||||
if (void 0 !== e) {
|
||||
var i = e.call(t, r || "default");
|
||||
if ("object" != _typeof(i)) return i;
|
||||
throw new TypeError("@@toPrimitive must return a primitive value.");
|
||||
}
|
||||
return ("string" === r ? String : Number)(t);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region \0@oxc-project+runtime@0.103.0/helpers/toPropertyKey.js
|
||||
function toPropertyKey(t) {
|
||||
var i = toPrimitive(t, "string");
|
||||
return "symbol" == _typeof(i) ? i : i + "";
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region \0@oxc-project+runtime@0.103.0/helpers/defineProperty.js
|
||||
function _defineProperty(e, r, t) {
|
||||
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
||||
value: t,
|
||||
enumerable: !0,
|
||||
configurable: !0,
|
||||
writable: !0
|
||||
}) : e[r] = t, e;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region \0@oxc-project+runtime@0.103.0/helpers/objectSpread2.js
|
||||
function ownKeys(e, r) {
|
||||
var t = Object.keys(e);
|
||||
if (Object.getOwnPropertySymbols) {
|
||||
var o = Object.getOwnPropertySymbols(e);
|
||||
r && (o = o.filter(function(r$1) {
|
||||
return Object.getOwnPropertyDescriptor(e, r$1).enumerable;
|
||||
})), t.push.apply(t, o);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
function _objectSpread2(e) {
|
||||
for (var r = 1; r < arguments.length; r++) {
|
||||
var t = null != arguments[r] ? arguments[r] : {};
|
||||
r % 2 ? ownKeys(Object(t), !0).forEach(function(r$1) {
|
||||
_defineProperty(e, r$1, t[r$1]);
|
||||
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r$1) {
|
||||
Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t, r$1));
|
||||
});
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/lib/fetch.ts
|
||||
const resolveFetch = (customFetch) => {
|
||||
if (customFetch) return (...args) => customFetch(...args);
|
||||
return (...args) => fetch(...args);
|
||||
};
|
||||
const resolveHeadersConstructor = () => {
|
||||
return Headers;
|
||||
};
|
||||
/**
|
||||
* New-format Supabase API keys (`sb_publishable_…` / `sb_secret_…`) are not JWTs and
|
||||
* must never be sent as a Bearer token — they belong only in the `apikey` header.
|
||||
* All other keys (legacy JWT keys, `sb_temp_…` temporary keys, unrecognized `sb_`
|
||||
* subtypes) keep the Bearer fallback.
|
||||
*/
|
||||
const isNewApiKey = (key) => key.startsWith("sb_publishable_") || key.startsWith("sb_secret_");
|
||||
const TEMP_KEY_PREFIX = "sb_temp_";
|
||||
const warnedKeySubtypes = /* @__PURE__ */ new Set();
|
||||
/**
|
||||
* Warn (once per subtype) when an `sb_` key isn't a subtype this SDK version recognizes.
|
||||
* Never throws — the server, not the SDK, decides key validity. The key value is never
|
||||
* included in the message.
|
||||
*/
|
||||
const checkApiKeyFormat = (key) => {
|
||||
var _key$match$, _key$match;
|
||||
if (!key.startsWith("sb_") || isNewApiKey(key) || key.startsWith(TEMP_KEY_PREFIX)) return;
|
||||
const subtype = (_key$match$ = (_key$match = key.match(/^sb_[a-zA-Z0-9]+_/)) === null || _key$match === void 0 ? void 0 : _key$match[0]) !== null && _key$match$ !== void 0 ? _key$match$ : "unknown";
|
||||
if (warnedKeySubtypes.has(subtype)) return;
|
||||
warnedKeySubtypes.add(subtype);
|
||||
console.warn("@supabase/supabase-js: Unrecognized Supabase API key format. The client will proceed and send this key as-is; if you see authentication errors you may need to upgrade @supabase/supabase-js to a version that recognizes this key type.");
|
||||
};
|
||||
const fetchWithAuth = (supabaseKey, supabaseUrl, getAccessToken, customFetch, tracePropagationOptions, options) => {
|
||||
const fetch$1 = resolveFetch(customFetch);
|
||||
const HeadersConstructor = resolveHeadersConstructor();
|
||||
const traceEnabled = (tracePropagationOptions === null || tracePropagationOptions === void 0 ? void 0 : tracePropagationOptions.enabled) === true;
|
||||
const respectSampling = (tracePropagationOptions === null || tracePropagationOptions === void 0 ? void 0 : tracePropagationOptions.respectSamplingDecision) !== false;
|
||||
const traceTargets = traceEnabled ? getDefaultPropagationTargets(supabaseUrl) : null;
|
||||
const allowKeyAsBearer = !((options === null || options === void 0 ? void 0 : options.omitApiKeyAsBearer) && isNewApiKey(supabaseKey));
|
||||
return async (input, init) => {
|
||||
const realToken = await getAccessToken();
|
||||
let headers = new HeadersConstructor(init === null || init === void 0 ? void 0 : init.headers);
|
||||
if (!headers.has("apikey")) headers.set("apikey", supabaseKey);
|
||||
if (!headers.has("Authorization")) {
|
||||
const bearer = realToken !== null && realToken !== void 0 ? realToken : allowKeyAsBearer ? supabaseKey : null;
|
||||
if (bearer) headers.set("Authorization", `Bearer ${bearer}`);
|
||||
}
|
||||
if (traceTargets) {
|
||||
const traceHeaders = await getTraceHeaders(input, traceTargets, respectSampling);
|
||||
if (traceHeaders) {
|
||||
if (traceHeaders.traceparent && !headers.has("traceparent")) headers.set("traceparent", traceHeaders.traceparent);
|
||||
if (traceHeaders.tracestate && !headers.has("tracestate")) headers.set("tracestate", traceHeaders.tracestate);
|
||||
if (traceHeaders.baggage && !headers.has("baggage")) headers.set("baggage", traceHeaders.baggage);
|
||||
}
|
||||
}
|
||||
return fetch$1(input, _objectSpread2(_objectSpread2({}, init), {}, { headers }));
|
||||
};
|
||||
};
|
||||
async function getTraceHeaders(input, targets, respectSampling) {
|
||||
if (!shouldPropagateToTarget(typeof input === "string" ? input : input instanceof URL ? input : input.url, targets)) return null;
|
||||
const traceContext = await extractTraceContext();
|
||||
if (!traceContext || !traceContext.traceparent) return null;
|
||||
if (respectSampling) {
|
||||
const parsed = parseTraceParent(traceContext.traceparent);
|
||||
if (parsed && !parsed.isSampled) return null;
|
||||
}
|
||||
return traceContext;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/lib/helpers.ts
|
||||
function normalizeTracePropagation(value) {
|
||||
return typeof value === "boolean" ? { enabled: value } : value;
|
||||
}
|
||||
function ensureTrailingSlash(url) {
|
||||
return url.endsWith("/") ? url : url + "/";
|
||||
}
|
||||
function applySettingDefaults(options, defaults) {
|
||||
var _DEFAULT_GLOBAL_OPTIO, _globalOptions$header, _ref, _tracePropagationOpti, _ref2, _tracePropagationOpti2;
|
||||
const { db: dbOptions, auth: authOptions, realtime: realtimeOptions, global: globalOptions } = options;
|
||||
const { db: DEFAULT_DB_OPTIONS$1, auth: DEFAULT_AUTH_OPTIONS$1, realtime: DEFAULT_REALTIME_OPTIONS$1, global: DEFAULT_GLOBAL_OPTIONS$1 } = defaults;
|
||||
const tracePropagationOptions = normalizeTracePropagation(options.tracePropagation);
|
||||
const DEFAULT_TRACE_PROPAGATION_OPTIONS$1 = normalizeTracePropagation(defaults.tracePropagation);
|
||||
const result = {
|
||||
db: _objectSpread2(_objectSpread2({}, DEFAULT_DB_OPTIONS$1), dbOptions),
|
||||
auth: _objectSpread2(_objectSpread2({}, DEFAULT_AUTH_OPTIONS$1), authOptions),
|
||||
realtime: _objectSpread2(_objectSpread2({}, DEFAULT_REALTIME_OPTIONS$1), realtimeOptions),
|
||||
storage: {},
|
||||
global: _objectSpread2(_objectSpread2(_objectSpread2({}, DEFAULT_GLOBAL_OPTIONS$1), globalOptions), {}, { headers: _objectSpread2(_objectSpread2({}, (_DEFAULT_GLOBAL_OPTIO = DEFAULT_GLOBAL_OPTIONS$1 === null || DEFAULT_GLOBAL_OPTIONS$1 === void 0 ? void 0 : DEFAULT_GLOBAL_OPTIONS$1.headers) !== null && _DEFAULT_GLOBAL_OPTIO !== void 0 ? _DEFAULT_GLOBAL_OPTIO : {}), (_globalOptions$header = globalOptions === null || globalOptions === void 0 ? void 0 : globalOptions.headers) !== null && _globalOptions$header !== void 0 ? _globalOptions$header : {}) }),
|
||||
tracePropagation: {
|
||||
enabled: (_ref = (_tracePropagationOpti = tracePropagationOptions === null || tracePropagationOptions === void 0 ? void 0 : tracePropagationOptions.enabled) !== null && _tracePropagationOpti !== void 0 ? _tracePropagationOpti : DEFAULT_TRACE_PROPAGATION_OPTIONS$1 === null || DEFAULT_TRACE_PROPAGATION_OPTIONS$1 === void 0 ? void 0 : DEFAULT_TRACE_PROPAGATION_OPTIONS$1.enabled) !== null && _ref !== void 0 ? _ref : false,
|
||||
respectSamplingDecision: (_ref2 = (_tracePropagationOpti2 = tracePropagationOptions === null || tracePropagationOptions === void 0 ? void 0 : tracePropagationOptions.respectSamplingDecision) !== null && _tracePropagationOpti2 !== void 0 ? _tracePropagationOpti2 : DEFAULT_TRACE_PROPAGATION_OPTIONS$1 === null || DEFAULT_TRACE_PROPAGATION_OPTIONS$1 === void 0 ? void 0 : DEFAULT_TRACE_PROPAGATION_OPTIONS$1.respectSamplingDecision) !== null && _ref2 !== void 0 ? _ref2 : true
|
||||
},
|
||||
accessToken: async () => ""
|
||||
};
|
||||
if (options.accessToken) result.accessToken = options.accessToken;
|
||||
else delete result.accessToken;
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Validates a Supabase client URL
|
||||
*
|
||||
* @param {string} supabaseUrl - The Supabase client URL string.
|
||||
* @returns {URL} - The validated base URL.
|
||||
* @throws {Error}
|
||||
*/
|
||||
function validateSupabaseUrl(supabaseUrl) {
|
||||
const trimmedUrl = supabaseUrl === null || supabaseUrl === void 0 ? void 0 : supabaseUrl.trim();
|
||||
if (!trimmedUrl) throw new Error("supabaseUrl is required.");
|
||||
if (!trimmedUrl.match(/^https?:\/\//i)) throw new Error("Invalid supabaseUrl: Must be a valid HTTP or HTTPS URL.");
|
||||
try {
|
||||
return new URL(ensureTrailingSlash(trimmedUrl));
|
||||
} catch (_unused) {
|
||||
throw Error("Invalid supabaseUrl: Provided URL is malformed.");
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/lib/SupabaseAuthClient.ts
|
||||
var SupabaseAuthClient = class extends AuthClient {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/SupabaseClient.ts
|
||||
/**
|
||||
* Supabase Client.
|
||||
*
|
||||
* An isomorphic Javascript client for interacting with Postgres.
|
||||
*/
|
||||
var SupabaseClient = class {
|
||||
/**
|
||||
* Create a new client for use in the browser.
|
||||
*
|
||||
* @category Initializing
|
||||
*
|
||||
* @param supabaseUrl The unique Supabase URL which is supplied when you create a new project in your project dashboard.
|
||||
* @param supabaseKey The unique Supabase Key which is supplied when you create a new project in your project dashboard.
|
||||
* @param options Optional configuration for the client:
|
||||
* - `db.schema` — You can switch in between schemas. The schema needs to be on the list of exposed schemas inside Supabase.
|
||||
* - `auth.autoRefreshToken` — Set to `true` if you want to automatically refresh the token before expiring.
|
||||
* - `auth.persistSession` — Set to `true` if you want to automatically save the user session into local storage.
|
||||
* - `auth.detectSessionInUrl` — Set to `true` if you want to automatically detect OAuth grants in the URL and sign in the user.
|
||||
* - `realtime` — Options passed along to the realtime-js constructor.
|
||||
* - `storage` — Options passed along to the storage-js constructor.
|
||||
* - `global.fetch` — A custom fetch implementation.
|
||||
* - `global.headers` — Any additional headers to send with each network request.
|
||||
*
|
||||
* @example Creating a client
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* // Create a single supabase client for interacting with your database
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
* ```
|
||||
*
|
||||
* @example With a custom domain
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* // Use a custom domain as the supabase URL
|
||||
* const supabase = createClient('https://my-custom-domain.com', 'your-publishable-key')
|
||||
* ```
|
||||
*
|
||||
* @example With additional parameters
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const options = {
|
||||
* db: {
|
||||
* schema: 'public',
|
||||
* },
|
||||
* auth: {
|
||||
* autoRefreshToken: true,
|
||||
* persistSession: true,
|
||||
* detectSessionInUrl: true
|
||||
* },
|
||||
* global: {
|
||||
* headers: { 'x-my-custom-header': 'my-app-name' },
|
||||
* },
|
||||
* }
|
||||
* const supabase = createClient("https://xyzcompany.supabase.co", "your-publishable-key", options)
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription With custom schemas
|
||||
* By default the API server points to the `public` schema. You can enable other database schemas within the Dashboard.
|
||||
* Go to [Settings > API > Exposed schemas](/dashboard/project/_/settings/api) and add the schema which you want to expose to the API.
|
||||
*
|
||||
* Note: each client connection can only access a single schema, so the code above can access the `other_schema` schema but cannot access the `public` schema.
|
||||
*
|
||||
* @example With custom schemas
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
* // Provide a custom schema. Defaults to "public".
|
||||
* db: { schema: 'other_schema' }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription Custom fetch implementation
|
||||
* `supabase-js` uses the runtime's global `fetch` to make HTTP requests,
|
||||
* but an alternative `fetch` implementation can be provided as an option.
|
||||
* This is useful in environments where the global `fetch` is unavailable or where you want to customize request behavior.
|
||||
*
|
||||
* @example Custom fetch implementation
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
* global: { fetch: fetch.bind(globalThis) }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription React Native options with AsyncStorage
|
||||
* For React Native we recommend using `AsyncStorage` as the storage implementation for Supabase Auth.
|
||||
*
|
||||
* @example React Native options with AsyncStorage
|
||||
* ```js
|
||||
* import 'react-native-url-polyfill/auto'
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
*
|
||||
* const supabase = createClient("https://xyzcompany.supabase.co", "your-publishable-key", {
|
||||
* auth: {
|
||||
* storage: AsyncStorage,
|
||||
* autoRefreshToken: true,
|
||||
* persistSession: true,
|
||||
* detectSessionInUrl: false,
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription React Native options with Expo SecureStore
|
||||
* If you wish to encrypt the user's session information, you can use `aes-js` and store the encryption key in Expo SecureStore.
|
||||
* The `aes-js` library, a reputable JavaScript-only implementation of the AES encryption algorithm in CTR mode.
|
||||
* A new 256-bit encryption key is generated using the `react-native-get-random-values` library.
|
||||
* This key is stored inside Expo's SecureStore, while the value is encrypted and placed inside AsyncStorage.
|
||||
*
|
||||
* Please make sure that:
|
||||
* - You keep the `expo-secure-store`, `aes-js` and `react-native-get-random-values` libraries up-to-date.
|
||||
* - Choose the correct [`SecureStoreOptions`](https://docs.expo.dev/versions/latest/sdk/securestore/#securestoreoptions) for your app's needs.
|
||||
* E.g. [`SecureStore.WHEN_UNLOCKED`](https://docs.expo.dev/versions/latest/sdk/securestore/#securestorewhen_unlocked) regulates when the data can be accessed.
|
||||
* - Carefully consider optimizations or other modifications to the above example, as those can lead to introducing subtle security vulnerabilities.
|
||||
*
|
||||
* @example React Native options with Expo SecureStore
|
||||
* ```ts
|
||||
* import 'react-native-url-polyfill/auto'
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
* import * as SecureStore from 'expo-secure-store';
|
||||
* import * as aesjs from 'aes-js';
|
||||
* import 'react-native-get-random-values';
|
||||
*
|
||||
* // As Expo's SecureStore does not support values larger than 2048
|
||||
* // bytes, an AES-256 key is generated and stored in SecureStore, while
|
||||
* // it is used to encrypt/decrypt values stored in AsyncStorage.
|
||||
* class LargeSecureStore {
|
||||
* private async _encrypt(key: string, value: string) {
|
||||
* const encryptionKey = crypto.getRandomValues(new Uint8Array(256 / 8));
|
||||
*
|
||||
* const cipher = new aesjs.ModeOfOperation.ctr(encryptionKey, new aesjs.Counter(1));
|
||||
* const encryptedBytes = cipher.encrypt(aesjs.utils.utf8.toBytes(value));
|
||||
*
|
||||
* await SecureStore.setItemAsync(key, aesjs.utils.hex.fromBytes(encryptionKey));
|
||||
*
|
||||
* return aesjs.utils.hex.fromBytes(encryptedBytes);
|
||||
* }
|
||||
*
|
||||
* private async _decrypt(key: string, value: string) {
|
||||
* const encryptionKeyHex = await SecureStore.getItemAsync(key);
|
||||
* if (!encryptionKeyHex) {
|
||||
* return encryptionKeyHex;
|
||||
* }
|
||||
*
|
||||
* const cipher = new aesjs.ModeOfOperation.ctr(aesjs.utils.hex.toBytes(encryptionKeyHex), new aesjs.Counter(1));
|
||||
* const decryptedBytes = cipher.decrypt(aesjs.utils.hex.toBytes(value));
|
||||
*
|
||||
* return aesjs.utils.utf8.fromBytes(decryptedBytes);
|
||||
* }
|
||||
*
|
||||
* async getItem(key: string) {
|
||||
* const encrypted = await AsyncStorage.getItem(key);
|
||||
* if (!encrypted) { return encrypted; }
|
||||
*
|
||||
* return await this._decrypt(key, encrypted);
|
||||
* }
|
||||
*
|
||||
* async removeItem(key: string) {
|
||||
* await AsyncStorage.removeItem(key);
|
||||
* await SecureStore.deleteItemAsync(key);
|
||||
* }
|
||||
*
|
||||
* async setItem(key: string, value: string) {
|
||||
* const encrypted = await this._encrypt(key, value);
|
||||
*
|
||||
* await AsyncStorage.setItem(key, encrypted);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* const supabase = createClient("https://xyzcompany.supabase.co", "your-publishable-key", {
|
||||
* auth: {
|
||||
* storage: new LargeSecureStore(),
|
||||
* autoRefreshToken: true,
|
||||
* persistSession: true,
|
||||
* detectSessionInUrl: false,
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example With a database query
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
*
|
||||
* const { data } = await supabase.from('profiles').select('*')
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription With OpenTelemetry tracing
|
||||
* Opt in to W3C trace context propagation so the `trace_id` from your
|
||||
* client-side spans is attached to Supabase requests and appears in API
|
||||
* Gateway and Edge Function logs. Requires `@opentelemetry/api` to be
|
||||
* installed in your application. See [Tracing with the JS SDK](https://supabase.com/docs/guides/telemetry/client-side-tracing).
|
||||
*
|
||||
* @example With OpenTelemetry tracing
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import { trace } from '@opentelemetry/api'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
* tracePropagation: true,
|
||||
* })
|
||||
*
|
||||
* const tracer = trace.getTracer('my-app')
|
||||
*
|
||||
* await tracer.startActiveSpan('fetch-users', async (span) => {
|
||||
* // Outgoing request carries the active trace context.
|
||||
* const { data, error } = await supabase.from('users').select('*')
|
||||
* span.end()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
constructor(supabaseUrl, supabaseKey, options) {
|
||||
var _settings$auth$storag, _settings$global$head;
|
||||
this.supabaseUrl = supabaseUrl;
|
||||
this.supabaseKey = supabaseKey;
|
||||
const baseUrl = validateSupabaseUrl(supabaseUrl);
|
||||
if (!supabaseKey) throw new Error("supabaseKey is required.");
|
||||
checkApiKeyFormat(supabaseKey);
|
||||
this.realtimeUrl = new URL("realtime/v1", baseUrl);
|
||||
this.realtimeUrl.protocol = this.realtimeUrl.protocol.replace("http", "ws");
|
||||
this.authUrl = new URL("auth/v1", baseUrl);
|
||||
this.storageUrl = new URL("storage/v1", baseUrl);
|
||||
this.functionsUrl = new URL("functions/v1", baseUrl);
|
||||
const defaultStorageKey = `sb-${baseUrl.hostname.split(".")[0]}-auth-token`;
|
||||
const DEFAULTS = {
|
||||
db: DEFAULT_DB_OPTIONS,
|
||||
realtime: DEFAULT_REALTIME_OPTIONS,
|
||||
auth: _objectSpread2(_objectSpread2({}, DEFAULT_AUTH_OPTIONS), {}, { storageKey: defaultStorageKey }),
|
||||
global: DEFAULT_GLOBAL_OPTIONS,
|
||||
tracePropagation: DEFAULT_TRACE_PROPAGATION_OPTIONS
|
||||
};
|
||||
const settings = applySettingDefaults(options !== null && options !== void 0 ? options : {}, DEFAULTS);
|
||||
this.settings = settings;
|
||||
this.storageKey = (_settings$auth$storag = settings.auth.storageKey) !== null && _settings$auth$storag !== void 0 ? _settings$auth$storag : "";
|
||||
this.headers = (_settings$global$head = settings.global.headers) !== null && _settings$global$head !== void 0 ? _settings$global$head : {};
|
||||
if (!settings.accessToken) {
|
||||
var _settings$auth;
|
||||
this.auth = this._initSupabaseAuthClient((_settings$auth = settings.auth) !== null && _settings$auth !== void 0 ? _settings$auth : {}, this.headers, settings.global.fetch);
|
||||
} else {
|
||||
this.accessToken = settings.accessToken;
|
||||
this.auth = new Proxy({}, { get: (_, prop) => {
|
||||
throw new Error(`@supabase/supabase-js: Supabase Client is configured with the accessToken option, accessing supabase.auth.${String(prop)} is not possible`);
|
||||
} });
|
||||
}
|
||||
this.fetch = fetchWithAuth(supabaseKey, supabaseUrl, this._getSessionToken.bind(this), settings.global.fetch, settings.tracePropagation);
|
||||
this.functionsFetch = fetchWithAuth(supabaseKey, supabaseUrl, this._getSessionToken.bind(this), settings.global.fetch, settings.tracePropagation, { omitApiKeyAsBearer: true });
|
||||
this.realtime = this._initRealtimeClient(_objectSpread2({
|
||||
headers: this.headers,
|
||||
accessToken: this._getAccessToken.bind(this),
|
||||
fetch: this.fetch
|
||||
}, settings.realtime));
|
||||
if (this.accessToken) Promise.resolve(this.accessToken()).then((token) => this.realtime.setAuth(token)).catch((e) => console.warn("Failed to set initial Realtime auth token:", e));
|
||||
this.rest = new PostgrestClient(new URL("rest/v1", baseUrl).href, {
|
||||
headers: this.headers,
|
||||
schema: settings.db.schema,
|
||||
fetch: this.fetch,
|
||||
timeout: settings.db.timeout,
|
||||
urlLengthLimit: settings.db.urlLengthLimit
|
||||
});
|
||||
this.storage = new StorageClient(this.storageUrl.href, this.headers, this.fetch, options === null || options === void 0 ? void 0 : options.storage);
|
||||
if (!settings.accessToken) this._listenForAuthEvents();
|
||||
}
|
||||
/**
|
||||
* Supabase Functions allows you to deploy and invoke edge functions.
|
||||
*/
|
||||
get functions() {
|
||||
return new FunctionsClient(this.functionsUrl.href, {
|
||||
headers: this.headers,
|
||||
customFetch: this.functionsFetch
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Perform a query on a table or a view.
|
||||
*
|
||||
* @param relation - The table or view name to query
|
||||
*/
|
||||
from(relation) {
|
||||
return this.rest.from(relation);
|
||||
}
|
||||
/**
|
||||
* Select a schema to query or perform an function (rpc) call.
|
||||
*
|
||||
* The schema needs to be on the list of exposed schemas inside Supabase.
|
||||
*
|
||||
* @param schema - The schema to query
|
||||
*/
|
||||
schema(schema) {
|
||||
return this.rest.schema(schema);
|
||||
}
|
||||
/**
|
||||
* Perform a function call.
|
||||
*
|
||||
* @param fn - The function name to call
|
||||
* @param args - The arguments to pass to the function call
|
||||
* @param options - Named parameters
|
||||
* @param options.head - When set to `true`, `data` will not be returned.
|
||||
* Useful if you only need the count.
|
||||
* @param options.get - When set to `true`, the function will be called with
|
||||
* read-only access mode.
|
||||
* @param options.count - Count algorithm to use to count rows returned by the
|
||||
* function. Only applicable for [set-returning
|
||||
* functions](https://www.postgresql.org/docs/current/functions-srf.html).
|
||||
*
|
||||
* `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the
|
||||
* hood.
|
||||
*
|
||||
* `"planned"`: Approximated but fast count algorithm. Uses the Postgres
|
||||
* statistics under the hood.
|
||||
*
|
||||
* `"estimated"`: Uses exact count for low numbers and planned count for high
|
||||
* numbers.
|
||||
*/
|
||||
rpc(fn, args = {}, options = {
|
||||
head: false,
|
||||
get: false,
|
||||
count: void 0
|
||||
}) {
|
||||
return this.rest.rpc(fn, args, options);
|
||||
}
|
||||
/**
|
||||
* Creates a Realtime channel with Broadcast, Presence, and Postgres Changes.
|
||||
*
|
||||
* @param {string} name - The name of the Realtime channel.
|
||||
* @param {Object} opts - The options to pass to the Realtime channel.
|
||||
*
|
||||
* @category Realtime
|
||||
*/
|
||||
channel(name, opts = { config: {} }) {
|
||||
return this.realtime.channel(name, opts);
|
||||
}
|
||||
/**
|
||||
* Returns all Realtime channels.
|
||||
*
|
||||
* @category Realtime
|
||||
*
|
||||
* @example Get all channels
|
||||
* ```js
|
||||
* const channels = supabase.getChannels()
|
||||
* ```
|
||||
*/
|
||||
getChannels() {
|
||||
return this.realtime.getChannels();
|
||||
}
|
||||
/**
|
||||
* Unsubscribes and removes Realtime channel from Realtime client.
|
||||
*
|
||||
* @param {RealtimeChannel} channel - The name of the Realtime channel.
|
||||
*
|
||||
*
|
||||
* @category Realtime
|
||||
*
|
||||
* @remarks
|
||||
* - Removing a channel is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
|
||||
*
|
||||
* @example Removes a channel
|
||||
* ```js
|
||||
* supabase.removeChannel(myChannel)
|
||||
* ```
|
||||
*/
|
||||
removeChannel(channel) {
|
||||
return this.realtime.removeChannel(channel);
|
||||
}
|
||||
/**
|
||||
* Unsubscribes and removes all Realtime channels from Realtime client.
|
||||
*
|
||||
* @category Realtime
|
||||
*
|
||||
* @remarks
|
||||
* - Removing channels is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
|
||||
*
|
||||
* @example Remove all channels
|
||||
* ```js
|
||||
* supabase.removeAllChannels()
|
||||
* ```
|
||||
*/
|
||||
removeAllChannels() {
|
||||
return this.realtime.removeAllChannels();
|
||||
}
|
||||
/**
|
||||
* The raw session token — the custom `accessToken` result or the signed-in user's JWT —
|
||||
* or `null` when there is no session. Unlike {@link _getAccessToken} it does not fall back
|
||||
* to `supabaseKey`, so callers can distinguish "no session" from "has session".
|
||||
*/
|
||||
async _getSessionToken() {
|
||||
var _this = this;
|
||||
var _data$session$access_, _data$session;
|
||||
if (_this.accessToken) return await _this.accessToken();
|
||||
const { data } = await _this.auth.getSession();
|
||||
return (_data$session$access_ = (_data$session = data.session) === null || _data$session === void 0 ? void 0 : _data$session.access_token) !== null && _data$session$access_ !== void 0 ? _data$session$access_ : null;
|
||||
}
|
||||
async _getAccessToken() {
|
||||
var _this2 = this;
|
||||
var _await$this$_getSessi;
|
||||
return (_await$this$_getSessi = await _this2._getSessionToken()) !== null && _await$this$_getSessi !== void 0 ? _await$this$_getSessi : _this2.supabaseKey;
|
||||
}
|
||||
_initSupabaseAuthClient({ autoRefreshToken, persistSession, detectSessionInUrl, storage, userStorage, storageKey, flowType, lock, debug, throwOnError, experimental, lockAcquireTimeout, skipAutoInitialize }, headers, fetch$1) {
|
||||
const authHeaders = {
|
||||
Authorization: `Bearer ${this.supabaseKey}`,
|
||||
apikey: `${this.supabaseKey}`
|
||||
};
|
||||
return new SupabaseAuthClient({
|
||||
url: this.authUrl.href,
|
||||
headers: _objectSpread2(_objectSpread2({}, authHeaders), headers),
|
||||
storageKey,
|
||||
autoRefreshToken,
|
||||
persistSession,
|
||||
detectSessionInUrl,
|
||||
storage,
|
||||
userStorage,
|
||||
flowType,
|
||||
lock,
|
||||
debug,
|
||||
throwOnError,
|
||||
experimental,
|
||||
fetch: fetch$1,
|
||||
lockAcquireTimeout,
|
||||
skipAutoInitialize,
|
||||
hasCustomAuthorizationHeader: Object.keys(this.headers).some((key) => key.toLowerCase() === "authorization")
|
||||
});
|
||||
}
|
||||
_initRealtimeClient(options) {
|
||||
return new RealtimeClient(this.realtimeUrl.href, _objectSpread2(_objectSpread2({}, options), {}, { params: _objectSpread2(_objectSpread2({}, { apikey: this.supabaseKey }), options === null || options === void 0 ? void 0 : options.params) }));
|
||||
}
|
||||
_listenForAuthEvents() {
|
||||
return this.auth.onAuthStateChange((event, session) => {
|
||||
this._handleTokenChanged(event, "CLIENT", session === null || session === void 0 ? void 0 : session.access_token);
|
||||
});
|
||||
}
|
||||
_handleTokenChanged(event, source, token) {
|
||||
if ((event === "TOKEN_REFRESHED" || event === "SIGNED_IN" || event === "INITIAL_SESSION") && this.changedAccessToken !== token) {
|
||||
this.changedAccessToken = token;
|
||||
this.realtime.setAuth(token);
|
||||
} else if (event === "SIGNED_OUT") {
|
||||
this.realtime.setAuth();
|
||||
if (source == "STORAGE") this.auth.signOut();
|
||||
this.changedAccessToken = void 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region src/index.ts
|
||||
/**
|
||||
* Creates a new Supabase Client.
|
||||
*
|
||||
* @example Creating a Supabase client
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
* const { data, error } = await supabase.from('profiles').select('*')
|
||||
* ```
|
||||
*/
|
||||
const createClient = (supabaseUrl, supabaseKey, options) => {
|
||||
return new SupabaseClient(supabaseUrl, supabaseKey, options);
|
||||
};
|
||||
function shouldShowDeprecationWarning() {
|
||||
if (typeof window !== "undefined" || globalThis["Deno"] !== void 0) return false;
|
||||
const _process = globalThis["process"];
|
||||
if (!_process) return false;
|
||||
const processVersion = _process["version"];
|
||||
if (processVersion === void 0 || processVersion === null) return false;
|
||||
const versionMatch = processVersion.match(/^v(\d+)\./);
|
||||
if (!versionMatch) return false;
|
||||
return parseInt(versionMatch[1], 10) <= 20;
|
||||
}
|
||||
if (shouldShowDeprecationWarning()) console.warn("⚠️ Node.js 20 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 22 or later. For more information, visit: https://github.com/orgs/supabase/discussions/45715");
|
||||
|
||||
//#endregion
|
||||
export { FunctionRegion, FunctionsError, FunctionsFetchError, FunctionsHttpError, FunctionsRelayError, PostgrestError, StorageApiError, SupabaseClient, createClient };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+11
File diff suppressed because one or more lines are too long
+25
@@ -0,0 +1,25 @@
|
||||
# Migration notes for `@supabase/supabase-js`
|
||||
|
||||
Each file in this directory describes one migration theme — what changed in `@supabase/supabase-js`, who is affected, and what callers need to do.
|
||||
|
||||
Files are shipped with the npm package, so the migration notes you see here are pinned to the version of `@supabase/supabase-js` you have installed. Upgrading the package brings the relevant migration notes along with it.
|
||||
|
||||
## How agents should use this directory
|
||||
|
||||
When helping a developer upgrade `@supabase/supabase-js`:
|
||||
|
||||
1. Read the migration files in `node_modules/@supabase/supabase-js/migrations/` for the version they have installed.
|
||||
2. Cross-reference against the version they are upgrading to.
|
||||
3. Apply the migration steps described in each relevant file.
|
||||
|
||||
## How humans should use this directory
|
||||
|
||||
Browse the files for the migration theme you care about. Each file is self-contained and explains its own scope, audience, and steps.
|
||||
|
||||
## File naming
|
||||
|
||||
One file per migration theme, named by topic rather than version (e.g. `<theme>.md`, kebab-case). A single version can ship multiple theme files; a single theme can span multiple versions. Each file documents its own `Since` / `Will require action by` version range internally.
|
||||
|
||||
## Cross-cutting migration notes
|
||||
|
||||
Migrations that span multiple Supabase packages (e.g. Node.js version drops, monorepo restructures) live in [`docs/MIGRATION.md`](../../../../docs/MIGRATION.md) at the repository root, not here. This directory is scoped to `@supabase/supabase-js` only.
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"name": "@supabase/supabase-js",
|
||||
"version": "2.110.8",
|
||||
"description": "Isomorphic Javascript SDK for Supabase",
|
||||
"keywords": [
|
||||
"javascript",
|
||||
"typescript",
|
||||
"supabase"
|
||||
],
|
||||
"homepage": "https://github.com/supabase/supabase-js/tree/master/packages/core/supabase-js",
|
||||
"bugs": "https://github.com/supabase/supabase-js/issues",
|
||||
"license": "MIT",
|
||||
"author": "Supabase",
|
||||
"files": [
|
||||
"dist",
|
||||
"src",
|
||||
"migrations",
|
||||
"AGENTS.md"
|
||||
],
|
||||
"main": "dist/index.cjs",
|
||||
"module": "dist/index.mjs",
|
||||
"types": "dist/index.d.cts",
|
||||
"exports": {
|
||||
".": {
|
||||
"react-native": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
}
|
||||
},
|
||||
"./cors": {
|
||||
"react-native": {
|
||||
"types": "./dist/cors.d.cts",
|
||||
"default": "./dist/cors.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/cors.d.mts",
|
||||
"default": "./dist/cors.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/cors.d.cts",
|
||||
"default": "./dist/cors.cjs"
|
||||
}
|
||||
},
|
||||
"./dist/*": "./dist/*",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/supabase/supabase-js.git",
|
||||
"directory": "packages/core/supabase-js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@supabase/auth-js": "2.110.8",
|
||||
"@supabase/functions-js": "2.110.8",
|
||||
"@supabase/realtime-js": "2.110.8",
|
||||
"@supabase/storage-js": "2.110.8",
|
||||
"@supabase/postgrest-js": "2.110.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "^0.18.2",
|
||||
"@jest/globals": "^30.0.0",
|
||||
"@jest/types": "^30.0.0",
|
||||
"@types/jest": "30.0.0",
|
||||
"@types/jsonwebtoken": "^8.5.8",
|
||||
"@types/node": "20.19.9",
|
||||
"jest": "30.4.2",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"jsr": "^0.13.5",
|
||||
"puppeteer": "^24.9.0",
|
||||
"ts-jest": "^29.4.9",
|
||||
"tsd": "^0.33.0",
|
||||
"tsdown": "^0.18.0",
|
||||
"typedoc": "^0.27.9",
|
||||
"typescript": "~5.8.3",
|
||||
"@supabase/tracing": "0.0.0-automated"
|
||||
},
|
||||
"jsdelivr": "dist/umd/supabase.js",
|
||||
"unpkg": "dist/umd/supabase.js",
|
||||
"nx": {
|
||||
"targets": {
|
||||
"test:integration:browser": {
|
||||
"dependsOn": [
|
||||
{
|
||||
"projects": [
|
||||
"storage-js"
|
||||
],
|
||||
"target": "build"
|
||||
}
|
||||
]
|
||||
},
|
||||
"test:edge-functions": {
|
||||
"dependsOn": [
|
||||
{
|
||||
"projects": [
|
||||
"storage-js"
|
||||
],
|
||||
"target": "build"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown",
|
||||
"build:watch": "tsdown --watch",
|
||||
"test": "npm run test:types && npm run test:run",
|
||||
"test:all": "npm run test:types && npm run test:run && npm run test:integration && npm run test:integration:browser",
|
||||
"test:run": "jest --runInBand --detectOpenHandles",
|
||||
"test:unit": "jest --runInBand --detectOpenHandles test/unit",
|
||||
"test:coverage": "jest --runInBand --coverage --testPathIgnorePatterns=\"test/integration|test/deno|\\.[mc]js$\"",
|
||||
"test:integration": "jest --runInBand --detectOpenHandles test/integration.test.ts",
|
||||
"test:integration:browser": "deno test --allow-all --node-modules-dir=auto test/integration.browser.test.ts",
|
||||
"test:edge-functions": "cd test/deno && npm run test:edge-functions",
|
||||
"test:deno": "cd test/deno && npm run test",
|
||||
"test:watch": "jest --watch --verbose false --silent false",
|
||||
"test:node:playwright": "cd test/integration/node-browser && npm install && cp ../../../dist/umd/supabase.js . && npm run test",
|
||||
"test:bun": "cd test/integration/bun && bun install && bun test",
|
||||
"test:expo": "cd test/integration/expo && npm test",
|
||||
"test:next": "cd test/integration/next && npm test",
|
||||
"test:types": "tsd --files test/types/index.test-d.ts && tsd --typings dist/cors.d.cts --files test/types/cors.test-d.ts && jsr publish --dry-run --allow-dirty",
|
||||
"test:exports": "attw --pack . --ignore-rules no-resolution",
|
||||
"test:esm": "node test/module-resolution.test.mjs && node test/module-resolution-cors.test.mjs",
|
||||
"test:cjs": "node test/module-resolution.test.cjs && node test/module-resolution-cors.test.cjs",
|
||||
"test:hermes-compat": "node test/bundle-hermes-compat.test.cjs",
|
||||
"test:module-resolution": "npm run test:exports && npm run test:esm && npm run test:cjs && npm run test:hermes-compat",
|
||||
"docs": "typedoc --options ../../../typedoc.base.mjs --entryPoints src/index.ts --entryPoints src/cors.ts --out docs/v2",
|
||||
"docs:json": "typedoc --options ../../../typedoc.base.mjs --entryPoints src/index.ts --entryPoints src/cors.ts --json docs/v2/spec.json --excludeExternals",
|
||||
"serve:coverage": "pnpm nx test:coverage supabase-js && pnpm dlx serve test/coverage",
|
||||
"update:test-deps": "pnpm run update:test-deps:expo && pnpm run update:test-deps:next && pnpm run update:test-deps:deno && pnpm run update:test-deps:bun",
|
||||
"update:test-deps:expo": "cd test/integration/expo && pnpm install --ignore-workspace",
|
||||
"update:test-deps:next": "cd test/integration/next && pnpm install --ignore-workspace",
|
||||
"update:test-deps:deno": "cd test/deno && pnpm install --ignore-workspace",
|
||||
"update:test-deps:bun": "cd test/integration/bun && bun install"
|
||||
}
|
||||
}
|
||||
+683
@@ -0,0 +1,683 @@
|
||||
import type { AuthChangeEvent } from '@supabase/auth-js'
|
||||
import { FunctionsClient } from '@supabase/functions-js'
|
||||
import {
|
||||
PostgrestClient,
|
||||
type PostgrestFilterBuilder,
|
||||
type PostgrestQueryBuilder,
|
||||
} from '@supabase/postgrest-js'
|
||||
import {
|
||||
type RealtimeChannel,
|
||||
type RealtimeChannelOptions,
|
||||
RealtimeClient,
|
||||
type RealtimeClientOptions,
|
||||
type RealtimeRemoveChannelResponse,
|
||||
} from '@supabase/realtime-js'
|
||||
import { StorageClient as SupabaseStorageClient } from '@supabase/storage-js'
|
||||
import {
|
||||
DEFAULT_AUTH_OPTIONS,
|
||||
DEFAULT_DB_OPTIONS,
|
||||
DEFAULT_GLOBAL_OPTIONS,
|
||||
DEFAULT_REALTIME_OPTIONS,
|
||||
DEFAULT_TRACE_PROPAGATION_OPTIONS,
|
||||
} from './lib/constants'
|
||||
import { checkApiKeyFormat, fetchWithAuth } from './lib/fetch'
|
||||
import {
|
||||
applySettingDefaults,
|
||||
validateSupabaseUrl,
|
||||
type ResolvedSupabaseClientOptions,
|
||||
} from './lib/helpers'
|
||||
import { SupabaseAuthClient } from './lib/SupabaseAuthClient'
|
||||
import type {
|
||||
Fetch,
|
||||
GenericSchema,
|
||||
SupabaseAuthClientOptions,
|
||||
SupabaseClientOptions,
|
||||
} from './lib/types'
|
||||
import { GetRpcFunctionFilterBuilderByArgs } from './lib/rest/types/common/rpc'
|
||||
|
||||
/**
|
||||
* Supabase Client.
|
||||
*
|
||||
* An isomorphic Javascript client for interacting with Postgres.
|
||||
*/
|
||||
export default class SupabaseClient<
|
||||
Database = any,
|
||||
// The second type parameter is also used for specifying db_schema, so we
|
||||
// support both cases.
|
||||
// TODO: Allow setting db_schema from ClientOptions.
|
||||
SchemaNameOrClientOptions extends
|
||||
| (string & keyof Omit<Database, '__InternalSupabase'>)
|
||||
| { PostgrestVersion: string } = 'public' extends keyof Omit<Database, '__InternalSupabase'>
|
||||
? 'public'
|
||||
: string & keyof Omit<Database, '__InternalSupabase'>,
|
||||
SchemaName extends string & keyof Omit<Database, '__InternalSupabase'> =
|
||||
SchemaNameOrClientOptions extends string & keyof Omit<Database, '__InternalSupabase'>
|
||||
? SchemaNameOrClientOptions
|
||||
: 'public' extends keyof Omit<Database, '__InternalSupabase'>
|
||||
? 'public'
|
||||
: string & keyof Omit<Omit<Database, '__InternalSupabase'>, '__InternalSupabase'>,
|
||||
Schema extends Omit<Database, '__InternalSupabase'>[SchemaName] extends GenericSchema
|
||||
? Omit<Database, '__InternalSupabase'>[SchemaName]
|
||||
: never = Omit<Database, '__InternalSupabase'>[SchemaName] extends GenericSchema
|
||||
? Omit<Database, '__InternalSupabase'>[SchemaName]
|
||||
: never,
|
||||
ClientOptions extends { PostgrestVersion: string } = SchemaNameOrClientOptions extends string &
|
||||
keyof Omit<Database, '__InternalSupabase'>
|
||||
? // If the version isn't explicitly set, look for it in the __InternalSupabase object to infer the right version
|
||||
Database extends { __InternalSupabase: { PostgrestVersion: string } }
|
||||
? Database['__InternalSupabase']
|
||||
: // otherwise default to 12
|
||||
{ PostgrestVersion: '12' }
|
||||
: SchemaNameOrClientOptions extends { PostgrestVersion: string }
|
||||
? SchemaNameOrClientOptions
|
||||
: never,
|
||||
> {
|
||||
/**
|
||||
* Supabase Auth allows you to create and manage user sessions for access to data that is secured by access policies.
|
||||
*/
|
||||
auth: SupabaseAuthClient
|
||||
realtime: RealtimeClient
|
||||
/**
|
||||
* Supabase Storage allows you to manage user-generated content, such as photos or videos.
|
||||
*/
|
||||
storage: SupabaseStorageClient
|
||||
|
||||
protected realtimeUrl: URL
|
||||
protected authUrl: URL
|
||||
protected storageUrl: URL
|
||||
protected functionsUrl: URL
|
||||
protected rest: PostgrestClient<Database, ClientOptions, SchemaName>
|
||||
protected storageKey: string
|
||||
protected fetch?: Fetch
|
||||
protected functionsFetch?: Fetch
|
||||
protected changedAccessToken?: string
|
||||
protected accessToken?: () => Promise<string | null>
|
||||
|
||||
protected headers: Record<string, string>
|
||||
protected settings?: ResolvedSupabaseClientOptions<SchemaName>
|
||||
|
||||
/**
|
||||
* Create a new client for use in the browser.
|
||||
*
|
||||
* @category Initializing
|
||||
*
|
||||
* @param supabaseUrl The unique Supabase URL which is supplied when you create a new project in your project dashboard.
|
||||
* @param supabaseKey The unique Supabase Key which is supplied when you create a new project in your project dashboard.
|
||||
* @param options Optional configuration for the client:
|
||||
* - `db.schema` — You can switch in between schemas. The schema needs to be on the list of exposed schemas inside Supabase.
|
||||
* - `auth.autoRefreshToken` — Set to `true` if you want to automatically refresh the token before expiring.
|
||||
* - `auth.persistSession` — Set to `true` if you want to automatically save the user session into local storage.
|
||||
* - `auth.detectSessionInUrl` — Set to `true` if you want to automatically detect OAuth grants in the URL and sign in the user.
|
||||
* - `realtime` — Options passed along to the realtime-js constructor.
|
||||
* - `storage` — Options passed along to the storage-js constructor.
|
||||
* - `global.fetch` — A custom fetch implementation.
|
||||
* - `global.headers` — Any additional headers to send with each network request.
|
||||
*
|
||||
* @example Creating a client
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* // Create a single supabase client for interacting with your database
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
* ```
|
||||
*
|
||||
* @example With a custom domain
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* // Use a custom domain as the supabase URL
|
||||
* const supabase = createClient('https://my-custom-domain.com', 'your-publishable-key')
|
||||
* ```
|
||||
*
|
||||
* @example With additional parameters
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const options = {
|
||||
* db: {
|
||||
* schema: 'public',
|
||||
* },
|
||||
* auth: {
|
||||
* autoRefreshToken: true,
|
||||
* persistSession: true,
|
||||
* detectSessionInUrl: true
|
||||
* },
|
||||
* global: {
|
||||
* headers: { 'x-my-custom-header': 'my-app-name' },
|
||||
* },
|
||||
* }
|
||||
* const supabase = createClient("https://xyzcompany.supabase.co", "your-publishable-key", options)
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription With custom schemas
|
||||
* By default the API server points to the `public` schema. You can enable other database schemas within the Dashboard.
|
||||
* Go to [Settings > API > Exposed schemas](/dashboard/project/_/settings/api) and add the schema which you want to expose to the API.
|
||||
*
|
||||
* Note: each client connection can only access a single schema, so the code above can access the `other_schema` schema but cannot access the `public` schema.
|
||||
*
|
||||
* @example With custom schemas
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
* // Provide a custom schema. Defaults to "public".
|
||||
* db: { schema: 'other_schema' }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription Custom fetch implementation
|
||||
* `supabase-js` uses the runtime's global `fetch` to make HTTP requests,
|
||||
* but an alternative `fetch` implementation can be provided as an option.
|
||||
* This is useful in environments where the global `fetch` is unavailable or where you want to customize request behavior.
|
||||
*
|
||||
* @example Custom fetch implementation
|
||||
* ```js
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
* global: { fetch: fetch.bind(globalThis) }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription React Native options with AsyncStorage
|
||||
* For React Native we recommend using `AsyncStorage` as the storage implementation for Supabase Auth.
|
||||
*
|
||||
* @example React Native options with AsyncStorage
|
||||
* ```js
|
||||
* import 'react-native-url-polyfill/auto'
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
*
|
||||
* const supabase = createClient("https://xyzcompany.supabase.co", "your-publishable-key", {
|
||||
* auth: {
|
||||
* storage: AsyncStorage,
|
||||
* autoRefreshToken: true,
|
||||
* persistSession: true,
|
||||
* detectSessionInUrl: false,
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription React Native options with Expo SecureStore
|
||||
* If you wish to encrypt the user's session information, you can use `aes-js` and store the encryption key in Expo SecureStore.
|
||||
* The `aes-js` library, a reputable JavaScript-only implementation of the AES encryption algorithm in CTR mode.
|
||||
* A new 256-bit encryption key is generated using the `react-native-get-random-values` library.
|
||||
* This key is stored inside Expo's SecureStore, while the value is encrypted and placed inside AsyncStorage.
|
||||
*
|
||||
* Please make sure that:
|
||||
* - You keep the `expo-secure-store`, `aes-js` and `react-native-get-random-values` libraries up-to-date.
|
||||
* - Choose the correct [`SecureStoreOptions`](https://docs.expo.dev/versions/latest/sdk/securestore/#securestoreoptions) for your app's needs.
|
||||
* E.g. [`SecureStore.WHEN_UNLOCKED`](https://docs.expo.dev/versions/latest/sdk/securestore/#securestorewhen_unlocked) regulates when the data can be accessed.
|
||||
* - Carefully consider optimizations or other modifications to the above example, as those can lead to introducing subtle security vulnerabilities.
|
||||
*
|
||||
* @example React Native options with Expo SecureStore
|
||||
* ```ts
|
||||
* import 'react-native-url-polyfill/auto'
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
* import * as SecureStore from 'expo-secure-store';
|
||||
* import * as aesjs from 'aes-js';
|
||||
* import 'react-native-get-random-values';
|
||||
*
|
||||
* // As Expo's SecureStore does not support values larger than 2048
|
||||
* // bytes, an AES-256 key is generated and stored in SecureStore, while
|
||||
* // it is used to encrypt/decrypt values stored in AsyncStorage.
|
||||
* class LargeSecureStore {
|
||||
* private async _encrypt(key: string, value: string) {
|
||||
* const encryptionKey = crypto.getRandomValues(new Uint8Array(256 / 8));
|
||||
*
|
||||
* const cipher = new aesjs.ModeOfOperation.ctr(encryptionKey, new aesjs.Counter(1));
|
||||
* const encryptedBytes = cipher.encrypt(aesjs.utils.utf8.toBytes(value));
|
||||
*
|
||||
* await SecureStore.setItemAsync(key, aesjs.utils.hex.fromBytes(encryptionKey));
|
||||
*
|
||||
* return aesjs.utils.hex.fromBytes(encryptedBytes);
|
||||
* }
|
||||
*
|
||||
* private async _decrypt(key: string, value: string) {
|
||||
* const encryptionKeyHex = await SecureStore.getItemAsync(key);
|
||||
* if (!encryptionKeyHex) {
|
||||
* return encryptionKeyHex;
|
||||
* }
|
||||
*
|
||||
* const cipher = new aesjs.ModeOfOperation.ctr(aesjs.utils.hex.toBytes(encryptionKeyHex), new aesjs.Counter(1));
|
||||
* const decryptedBytes = cipher.decrypt(aesjs.utils.hex.toBytes(value));
|
||||
*
|
||||
* return aesjs.utils.utf8.fromBytes(decryptedBytes);
|
||||
* }
|
||||
*
|
||||
* async getItem(key: string) {
|
||||
* const encrypted = await AsyncStorage.getItem(key);
|
||||
* if (!encrypted) { return encrypted; }
|
||||
*
|
||||
* return await this._decrypt(key, encrypted);
|
||||
* }
|
||||
*
|
||||
* async removeItem(key: string) {
|
||||
* await AsyncStorage.removeItem(key);
|
||||
* await SecureStore.deleteItemAsync(key);
|
||||
* }
|
||||
*
|
||||
* async setItem(key: string, value: string) {
|
||||
* const encrypted = await this._encrypt(key, value);
|
||||
*
|
||||
* await AsyncStorage.setItem(key, encrypted);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* const supabase = createClient("https://xyzcompany.supabase.co", "your-publishable-key", {
|
||||
* auth: {
|
||||
* storage: new LargeSecureStore(),
|
||||
* autoRefreshToken: true,
|
||||
* persistSession: true,
|
||||
* detectSessionInUrl: false,
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example With a database query
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
*
|
||||
* const { data } = await supabase.from('profiles').select('*')
|
||||
* ```
|
||||
*
|
||||
* @exampleDescription With OpenTelemetry tracing
|
||||
* Opt in to W3C trace context propagation so the `trace_id` from your
|
||||
* client-side spans is attached to Supabase requests and appears in API
|
||||
* Gateway and Edge Function logs. Requires `@opentelemetry/api` to be
|
||||
* installed in your application. See [Tracing with the JS SDK](https://supabase.com/docs/guides/telemetry/client-side-tracing).
|
||||
*
|
||||
* @example With OpenTelemetry tracing
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import { trace } from '@opentelemetry/api'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {
|
||||
* tracePropagation: true,
|
||||
* })
|
||||
*
|
||||
* const tracer = trace.getTracer('my-app')
|
||||
*
|
||||
* await tracer.startActiveSpan('fetch-users', async (span) => {
|
||||
* // Outgoing request carries the active trace context.
|
||||
* const { data, error } = await supabase.from('users').select('*')
|
||||
* span.end()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
constructor(
|
||||
protected supabaseUrl: string,
|
||||
protected supabaseKey: string,
|
||||
options?: SupabaseClientOptions<SchemaName>
|
||||
) {
|
||||
const baseUrl = validateSupabaseUrl(supabaseUrl)
|
||||
if (!supabaseKey) throw new Error('supabaseKey is required.')
|
||||
checkApiKeyFormat(supabaseKey)
|
||||
|
||||
this.realtimeUrl = new URL('realtime/v1', baseUrl)
|
||||
this.realtimeUrl.protocol = this.realtimeUrl.protocol.replace('http', 'ws')
|
||||
this.authUrl = new URL('auth/v1', baseUrl)
|
||||
this.storageUrl = new URL('storage/v1', baseUrl)
|
||||
this.functionsUrl = new URL('functions/v1', baseUrl)
|
||||
|
||||
// default storage key uses the supabase project ref as a namespace
|
||||
const defaultStorageKey = `sb-${baseUrl.hostname.split('.')[0]}-auth-token`
|
||||
const DEFAULTS = {
|
||||
db: DEFAULT_DB_OPTIONS,
|
||||
realtime: DEFAULT_REALTIME_OPTIONS,
|
||||
auth: { ...DEFAULT_AUTH_OPTIONS, storageKey: defaultStorageKey },
|
||||
global: DEFAULT_GLOBAL_OPTIONS,
|
||||
tracePropagation: DEFAULT_TRACE_PROPAGATION_OPTIONS,
|
||||
}
|
||||
|
||||
const settings = applySettingDefaults(options ?? {}, DEFAULTS)
|
||||
this.settings = settings
|
||||
|
||||
this.storageKey = settings.auth.storageKey ?? ''
|
||||
this.headers = settings.global.headers ?? {}
|
||||
|
||||
if (!settings.accessToken) {
|
||||
this.auth = this._initSupabaseAuthClient(
|
||||
settings.auth ?? {},
|
||||
this.headers,
|
||||
settings.global.fetch
|
||||
)
|
||||
} else {
|
||||
this.accessToken = settings.accessToken
|
||||
|
||||
this.auth = new Proxy<SupabaseAuthClient>({} as any, {
|
||||
get: (_, prop) => {
|
||||
throw new Error(
|
||||
`@supabase/supabase-js: Supabase Client is configured with the accessToken option, accessing supabase.auth.${String(
|
||||
prop
|
||||
)} is not possible`
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// The fetch wrappers receive the raw session token (null when there is no session) and
|
||||
// decide the `Authorization` fallback themselves, so the API-key fallback lives in one place.
|
||||
this.fetch = fetchWithAuth(
|
||||
supabaseKey,
|
||||
supabaseUrl,
|
||||
this._getSessionToken.bind(this),
|
||||
settings.global.fetch,
|
||||
settings.tracePropagation
|
||||
)
|
||||
// Edge Functions use a dedicated fetch that never falls back to a new-format API key in
|
||||
// the Authorization header (see `isNewApiKey` in ./lib/fetch). Other services use `this.fetch`.
|
||||
this.functionsFetch = fetchWithAuth(
|
||||
supabaseKey,
|
||||
supabaseUrl,
|
||||
this._getSessionToken.bind(this),
|
||||
settings.global.fetch,
|
||||
settings.tracePropagation,
|
||||
{ omitApiKeyAsBearer: true }
|
||||
)
|
||||
this.realtime = this._initRealtimeClient({
|
||||
headers: this.headers,
|
||||
accessToken: this._getAccessToken.bind(this),
|
||||
fetch: this.fetch,
|
||||
...settings.realtime,
|
||||
})
|
||||
if (this.accessToken) {
|
||||
// Start auth immediately to avoid race condition with channel subscriptions
|
||||
// Wrap Promise to avoid Firefox extension cross-context Promise access errors
|
||||
Promise.resolve(this.accessToken())
|
||||
.then((token) => this.realtime.setAuth(token))
|
||||
.catch((e) => console.warn('Failed to set initial Realtime auth token:', e))
|
||||
}
|
||||
|
||||
this.rest = new PostgrestClient(new URL('rest/v1', baseUrl).href, {
|
||||
headers: this.headers,
|
||||
schema: settings.db.schema,
|
||||
fetch: this.fetch,
|
||||
timeout: settings.db.timeout,
|
||||
urlLengthLimit: settings.db.urlLengthLimit,
|
||||
})
|
||||
|
||||
this.storage = new SupabaseStorageClient(
|
||||
this.storageUrl.href,
|
||||
this.headers,
|
||||
this.fetch,
|
||||
options?.storage
|
||||
)
|
||||
|
||||
if (!settings.accessToken) {
|
||||
this._listenForAuthEvents()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Supabase Functions allows you to deploy and invoke edge functions.
|
||||
*/
|
||||
get functions(): FunctionsClient {
|
||||
return new FunctionsClient(this.functionsUrl.href, {
|
||||
headers: this.headers,
|
||||
customFetch: this.functionsFetch,
|
||||
})
|
||||
}
|
||||
|
||||
// NOTE: signatures must be kept in sync with PostgrestClient.from
|
||||
from<
|
||||
TableName extends string & keyof Schema['Tables'],
|
||||
Table extends Schema['Tables'][TableName],
|
||||
>(relation: TableName): PostgrestQueryBuilder<ClientOptions, Schema, Table, TableName>
|
||||
from<ViewName extends string & keyof Schema['Views'], View extends Schema['Views'][ViewName]>(
|
||||
relation: ViewName
|
||||
): PostgrestQueryBuilder<ClientOptions, Schema, View, ViewName>
|
||||
/**
|
||||
* Perform a query on a table or a view.
|
||||
*
|
||||
* @param relation - The table or view name to query
|
||||
*/
|
||||
from(relation: string): PostgrestQueryBuilder<ClientOptions, Schema, any> {
|
||||
return this.rest.from(relation)
|
||||
}
|
||||
|
||||
// NOTE: signatures must be kept in sync with PostgrestClient.schema
|
||||
/**
|
||||
* Select a schema to query or perform an function (rpc) call.
|
||||
*
|
||||
* The schema needs to be on the list of exposed schemas inside Supabase.
|
||||
*
|
||||
* @param schema - The schema to query
|
||||
*/
|
||||
schema<DynamicSchema extends string & keyof Omit<Database, '__InternalSupabase'>>(
|
||||
schema: DynamicSchema
|
||||
): PostgrestClient<
|
||||
Database,
|
||||
ClientOptions,
|
||||
DynamicSchema,
|
||||
Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any
|
||||
> {
|
||||
return this.rest.schema<DynamicSchema>(schema)
|
||||
}
|
||||
|
||||
// NOTE: signatures must be kept in sync with PostgrestClient.rpc
|
||||
/**
|
||||
* Perform a function call.
|
||||
*
|
||||
* @param fn - The function name to call
|
||||
* @param args - The arguments to pass to the function call
|
||||
* @param options - Named parameters
|
||||
* @param options.head - When set to `true`, `data` will not be returned.
|
||||
* Useful if you only need the count.
|
||||
* @param options.get - When set to `true`, the function will be called with
|
||||
* read-only access mode.
|
||||
* @param options.count - Count algorithm to use to count rows returned by the
|
||||
* function. Only applicable for [set-returning
|
||||
* functions](https://www.postgresql.org/docs/current/functions-srf.html).
|
||||
*
|
||||
* `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the
|
||||
* hood.
|
||||
*
|
||||
* `"planned"`: Approximated but fast count algorithm. Uses the Postgres
|
||||
* statistics under the hood.
|
||||
*
|
||||
* `"estimated"`: Uses exact count for low numbers and planned count for high
|
||||
* numbers.
|
||||
*/
|
||||
rpc<
|
||||
FnName extends string & keyof Schema['Functions'],
|
||||
Args extends Schema['Functions'][FnName]['Args'] = never,
|
||||
FilterBuilder extends GetRpcFunctionFilterBuilderByArgs<Schema, FnName, Args> =
|
||||
GetRpcFunctionFilterBuilderByArgs<Schema, FnName, Args>,
|
||||
>(
|
||||
fn: FnName,
|
||||
args: Args = {} as Args,
|
||||
options: {
|
||||
head?: boolean
|
||||
get?: boolean
|
||||
count?: 'exact' | 'planned' | 'estimated'
|
||||
} = {
|
||||
head: false,
|
||||
get: false,
|
||||
count: undefined,
|
||||
}
|
||||
): PostgrestFilterBuilder<
|
||||
ClientOptions,
|
||||
Schema,
|
||||
FilterBuilder['Row'],
|
||||
FilterBuilder['Result'],
|
||||
FilterBuilder['RelationName'],
|
||||
FilterBuilder['Relationships'],
|
||||
'RPC'
|
||||
> {
|
||||
return this.rest.rpc(fn, args, options) as unknown as PostgrestFilterBuilder<
|
||||
ClientOptions,
|
||||
Schema,
|
||||
FilterBuilder['Row'],
|
||||
FilterBuilder['Result'],
|
||||
FilterBuilder['RelationName'],
|
||||
FilterBuilder['Relationships'],
|
||||
'RPC'
|
||||
>
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Realtime channel with Broadcast, Presence, and Postgres Changes.
|
||||
*
|
||||
* @param {string} name - The name of the Realtime channel.
|
||||
* @param {Object} opts - The options to pass to the Realtime channel.
|
||||
*
|
||||
* @category Realtime
|
||||
*/
|
||||
channel(name: string, opts: RealtimeChannelOptions = { config: {} }): RealtimeChannel {
|
||||
return this.realtime.channel(name, opts)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Realtime channels.
|
||||
*
|
||||
* @category Realtime
|
||||
*
|
||||
* @example Get all channels
|
||||
* ```js
|
||||
* const channels = supabase.getChannels()
|
||||
* ```
|
||||
*/
|
||||
getChannels(): RealtimeChannel[] {
|
||||
return this.realtime.getChannels()
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribes and removes Realtime channel from Realtime client.
|
||||
*
|
||||
* @param {RealtimeChannel} channel - The name of the Realtime channel.
|
||||
*
|
||||
*
|
||||
* @category Realtime
|
||||
*
|
||||
* @remarks
|
||||
* - Removing a channel is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
|
||||
*
|
||||
* @example Removes a channel
|
||||
* ```js
|
||||
* supabase.removeChannel(myChannel)
|
||||
* ```
|
||||
*/
|
||||
removeChannel(channel: RealtimeChannel): Promise<RealtimeRemoveChannelResponse> {
|
||||
return this.realtime.removeChannel(channel)
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribes and removes all Realtime channels from Realtime client.
|
||||
*
|
||||
* @category Realtime
|
||||
*
|
||||
* @remarks
|
||||
* - Removing channels is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
|
||||
*
|
||||
* @example Remove all channels
|
||||
* ```js
|
||||
* supabase.removeAllChannels()
|
||||
* ```
|
||||
*/
|
||||
removeAllChannels(): Promise<RealtimeRemoveChannelResponse[]> {
|
||||
return this.realtime.removeAllChannels()
|
||||
}
|
||||
|
||||
/**
|
||||
* The raw session token — the custom `accessToken` result or the signed-in user's JWT —
|
||||
* or `null` when there is no session. Unlike {@link _getAccessToken} it does not fall back
|
||||
* to `supabaseKey`, so callers can distinguish "no session" from "has session".
|
||||
*/
|
||||
private async _getSessionToken(): Promise<string | null> {
|
||||
if (this.accessToken) {
|
||||
return await this.accessToken()
|
||||
}
|
||||
|
||||
const { data } = await this.auth.getSession()
|
||||
|
||||
return data.session?.access_token ?? null
|
||||
}
|
||||
|
||||
private async _getAccessToken() {
|
||||
return (await this._getSessionToken()) ?? this.supabaseKey
|
||||
}
|
||||
|
||||
private _initSupabaseAuthClient(
|
||||
{
|
||||
autoRefreshToken,
|
||||
persistSession,
|
||||
detectSessionInUrl,
|
||||
storage,
|
||||
userStorage,
|
||||
storageKey,
|
||||
flowType,
|
||||
lock,
|
||||
debug,
|
||||
throwOnError,
|
||||
experimental,
|
||||
lockAcquireTimeout,
|
||||
skipAutoInitialize,
|
||||
}: SupabaseAuthClientOptions,
|
||||
headers?: Record<string, string>,
|
||||
fetch?: Fetch
|
||||
) {
|
||||
const authHeaders = {
|
||||
Authorization: `Bearer ${this.supabaseKey}`,
|
||||
apikey: `${this.supabaseKey}`,
|
||||
}
|
||||
return new SupabaseAuthClient({
|
||||
url: this.authUrl.href,
|
||||
headers: { ...authHeaders, ...headers },
|
||||
storageKey: storageKey,
|
||||
autoRefreshToken,
|
||||
persistSession,
|
||||
detectSessionInUrl,
|
||||
storage,
|
||||
userStorage,
|
||||
flowType,
|
||||
lock,
|
||||
debug,
|
||||
throwOnError,
|
||||
experimental,
|
||||
fetch,
|
||||
lockAcquireTimeout,
|
||||
skipAutoInitialize,
|
||||
// auth checks if there is a custom authorizaiton header using this flag
|
||||
// so it knows whether to return an error when getUser is called with no session
|
||||
hasCustomAuthorizationHeader: Object.keys(this.headers).some(
|
||||
(key) => key.toLowerCase() === 'authorization'
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
private _initRealtimeClient(options: RealtimeClientOptions) {
|
||||
return new RealtimeClient(this.realtimeUrl.href, {
|
||||
...options,
|
||||
params: { ...{ apikey: this.supabaseKey }, ...options?.params },
|
||||
})
|
||||
}
|
||||
|
||||
private _listenForAuthEvents() {
|
||||
const data = this.auth.onAuthStateChange((event, session) => {
|
||||
this._handleTokenChanged(event, 'CLIENT', session?.access_token)
|
||||
})
|
||||
return data
|
||||
}
|
||||
|
||||
private _handleTokenChanged(
|
||||
event: AuthChangeEvent,
|
||||
source: 'CLIENT' | 'STORAGE',
|
||||
token?: string
|
||||
) {
|
||||
if (
|
||||
(event === 'TOKEN_REFRESHED' || event === 'SIGNED_IN' || event === 'INITIAL_SESSION') &&
|
||||
this.changedAccessToken !== token
|
||||
) {
|
||||
this.changedAccessToken = token
|
||||
this.realtime.setAuth(token)
|
||||
} else if (event === 'SIGNED_OUT') {
|
||||
this.realtime.setAuth()
|
||||
if (source == 'STORAGE') this.auth.signOut()
|
||||
this.changedAccessToken = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Canonical CORS configuration for Supabase Edge Functions
|
||||
*
|
||||
* This module exports CORS headers that stay synchronized with the Supabase SDK.
|
||||
* When new headers are added to the SDK, they are automatically included here,
|
||||
* preventing CORS errors in Edge Functions.
|
||||
*
|
||||
* @example Basic usage
|
||||
* ```typescript
|
||||
* import { corsHeaders } from '@supabase/supabase-js/cors'
|
||||
*
|
||||
* Deno.serve(async (req) => {
|
||||
* if (req.method === 'OPTIONS') {
|
||||
* return new Response('ok', { headers: corsHeaders })
|
||||
* }
|
||||
*
|
||||
* return new Response(
|
||||
* JSON.stringify({ data: 'Hello' }),
|
||||
* { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
* )
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @module cors
|
||||
*/
|
||||
|
||||
/**
|
||||
* All custom headers sent by the Supabase SDK.
|
||||
* These headers need to be included in CORS configuration to prevent preflight failures.
|
||||
*
|
||||
* Headers:
|
||||
* - authorization: Bearer token for authentication
|
||||
* - x-client-info: Library version information
|
||||
* - apikey: Project API key
|
||||
* - content-type: Standard HTTP content type
|
||||
* - x-retry-count: Retry attempt number sent by postgrest-js on retried requests
|
||||
*/
|
||||
const SUPABASE_HEADERS = [
|
||||
'authorization',
|
||||
'x-client-info',
|
||||
'apikey',
|
||||
'content-type',
|
||||
'x-retry-count',
|
||||
].join(', ')
|
||||
|
||||
/**
|
||||
* All HTTP methods used by the Supabase SDK
|
||||
*/
|
||||
const SUPABASE_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'].join(', ')
|
||||
|
||||
/**
|
||||
* Type representing CORS headers as a record of header names to values
|
||||
*/
|
||||
export type CorsHeaders = Record<string, string>
|
||||
|
||||
/**
|
||||
* Default CORS headers for Supabase Edge Functions.
|
||||
*
|
||||
* Includes all headers sent by Supabase client libraries and allows all standard HTTP methods.
|
||||
* Use this for simple CORS configurations with wildcard origin.
|
||||
*
|
||||
* @example Basic usage
|
||||
* ```typescript
|
||||
* import { corsHeaders } from '@supabase/supabase-js/cors'
|
||||
*
|
||||
* Deno.serve(async (req) => {
|
||||
* if (req.method === 'OPTIONS') {
|
||||
* return new Response('ok', { headers: corsHeaders })
|
||||
* }
|
||||
*
|
||||
* return new Response(
|
||||
* JSON.stringify({ data: 'Hello' }),
|
||||
* { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
* )
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @category Edge Functions
|
||||
*/
|
||||
export const corsHeaders: CorsHeaders = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Headers': SUPABASE_HEADERS,
|
||||
'Access-Control-Allow-Methods': SUPABASE_METHODS,
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
import SupabaseClient from './SupabaseClient'
|
||||
import type { SupabaseClientOptions } from './lib/types'
|
||||
|
||||
export * from '@supabase/auth-js'
|
||||
export type { User as AuthUser, Session as AuthSession } from '@supabase/auth-js'
|
||||
export type {
|
||||
PostgrestResponse,
|
||||
PostgrestSingleResponse,
|
||||
PostgrestMaybeSingleResponse,
|
||||
PostgrestBuilder,
|
||||
PostgrestFilterBuilder,
|
||||
PostgrestTransformBuilder,
|
||||
PostgrestQueryBuilder,
|
||||
} from '@supabase/postgrest-js'
|
||||
export { PostgrestError } from '@supabase/postgrest-js'
|
||||
export { StorageApiError } from '@supabase/storage-js'
|
||||
export type { FunctionInvokeOptions } from '@supabase/functions-js'
|
||||
export {
|
||||
FunctionsHttpError,
|
||||
FunctionsFetchError,
|
||||
FunctionsRelayError,
|
||||
FunctionsError,
|
||||
FunctionRegion,
|
||||
} from '@supabase/functions-js'
|
||||
export * from '@supabase/realtime-js'
|
||||
export { default as SupabaseClient } from './SupabaseClient'
|
||||
export type {
|
||||
SupabaseClientOptions,
|
||||
TracePropagationOptions,
|
||||
QueryResult,
|
||||
QueryData,
|
||||
QueryError,
|
||||
DatabaseWithoutInternals,
|
||||
} from './lib/types'
|
||||
|
||||
/**
|
||||
* Creates a new Supabase Client.
|
||||
*
|
||||
* @example Creating a Supabase client
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
||||
* const { data, error } = await supabase.from('profiles').select('*')
|
||||
* ```
|
||||
*/
|
||||
export const createClient = <
|
||||
Database = any,
|
||||
SchemaNameOrClientOptions extends
|
||||
| (string & keyof Omit<Database, '__InternalSupabase'>)
|
||||
| { PostgrestVersion: string } = 'public' extends keyof Omit<Database, '__InternalSupabase'>
|
||||
? 'public'
|
||||
: string & keyof Omit<Database, '__InternalSupabase'>,
|
||||
SchemaName extends string & keyof Omit<Database, '__InternalSupabase'> =
|
||||
SchemaNameOrClientOptions extends string & keyof Omit<Database, '__InternalSupabase'>
|
||||
? SchemaNameOrClientOptions
|
||||
: 'public' extends keyof Omit<Database, '__InternalSupabase'>
|
||||
? 'public'
|
||||
: string & keyof Omit<Omit<Database, '__InternalSupabase'>, '__InternalSupabase'>,
|
||||
>(
|
||||
supabaseUrl: string,
|
||||
supabaseKey: string,
|
||||
options?: SupabaseClientOptions<SchemaName>
|
||||
): SupabaseClient<Database, SchemaNameOrClientOptions, SchemaName> => {
|
||||
return new SupabaseClient<Database, SchemaNameOrClientOptions, SchemaName>(
|
||||
supabaseUrl,
|
||||
supabaseKey,
|
||||
options
|
||||
)
|
||||
}
|
||||
|
||||
// Check for Node.js <= 20 deprecation
|
||||
function shouldShowDeprecationWarning(): boolean {
|
||||
// Skip in browser and Deno environments
|
||||
if (typeof window !== 'undefined' || (globalThis as any)['Deno'] !== undefined) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Skip if process is not available (e.g., Edge Runtime)
|
||||
// Use dynamic property access to avoid Next.js Edge Runtime static analysis warnings
|
||||
const _process = (globalThis as any)['process']
|
||||
if (!_process) {
|
||||
return false
|
||||
}
|
||||
|
||||
const processVersion = _process['version']
|
||||
if (processVersion === undefined || processVersion === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const versionMatch = processVersion.match(/^v(\d+)\./)
|
||||
if (!versionMatch) {
|
||||
return false
|
||||
}
|
||||
|
||||
const majorVersion = parseInt(versionMatch[1], 10)
|
||||
return majorVersion <= 20
|
||||
}
|
||||
|
||||
if (shouldShowDeprecationWarning()) {
|
||||
console.warn(
|
||||
`⚠️ Node.js 20 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. ` +
|
||||
`Please upgrade to Node.js 22 or later. ` +
|
||||
`For more information, visit: https://github.com/orgs/supabase/discussions/45715`
|
||||
)
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import { AuthClient } from '@supabase/auth-js'
|
||||
import { SupabaseAuthClientOptions } from './types'
|
||||
|
||||
export class SupabaseAuthClient extends AuthClient {
|
||||
constructor(options: SupabaseAuthClientOptions) {
|
||||
super(options)
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// constants.ts
|
||||
import { RealtimeClientOptions } from '@supabase/realtime-js'
|
||||
import { SupabaseAuthClientOptions, TracePropagationOptions } from './types'
|
||||
import { version } from './version'
|
||||
|
||||
let JS_ENV = ''
|
||||
let JS_RUNTIME_VERSION: string | undefined
|
||||
// @ts-ignore
|
||||
if (typeof Deno !== 'undefined') {
|
||||
JS_ENV = 'deno'
|
||||
// @ts-ignore
|
||||
JS_RUNTIME_VERSION = Deno.version?.deno
|
||||
} else if (typeof document !== 'undefined') {
|
||||
JS_ENV = 'web'
|
||||
} else if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
|
||||
JS_ENV = 'react-native'
|
||||
} else {
|
||||
JS_ENV = 'node'
|
||||
const _process = (globalThis as any)['process']
|
||||
JS_RUNTIME_VERSION = _process?.['version']?.replace(/^v/, '')
|
||||
}
|
||||
|
||||
const _runtimeMeta = [`runtime=${JS_ENV}`]
|
||||
if (JS_RUNTIME_VERSION) {
|
||||
_runtimeMeta.push(`runtime-version=${JS_RUNTIME_VERSION}`)
|
||||
}
|
||||
|
||||
export const DEFAULT_HEADERS = {
|
||||
'X-Client-Info': `supabase-js/${version}; ${_runtimeMeta.join('; ')}`,
|
||||
}
|
||||
|
||||
export const DEFAULT_GLOBAL_OPTIONS = {
|
||||
headers: DEFAULT_HEADERS,
|
||||
}
|
||||
|
||||
export const DEFAULT_DB_OPTIONS = {
|
||||
schema: 'public',
|
||||
}
|
||||
|
||||
export const DEFAULT_AUTH_OPTIONS: SupabaseAuthClientOptions = {
|
||||
autoRefreshToken: true,
|
||||
persistSession: true,
|
||||
detectSessionInUrl: true,
|
||||
flowType: 'implicit',
|
||||
}
|
||||
|
||||
export const DEFAULT_REALTIME_OPTIONS: RealtimeClientOptions = {}
|
||||
|
||||
export const DEFAULT_TRACE_PROPAGATION_OPTIONS: TracePropagationOptions = {
|
||||
enabled: false,
|
||||
respectSamplingDecision: true,
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
import {
|
||||
extractTraceContext,
|
||||
parseTraceParent,
|
||||
shouldPropagateToTarget,
|
||||
getDefaultPropagationTargets,
|
||||
type TraceContext,
|
||||
type TracePropagationTarget,
|
||||
} from '@supabase/tracing'
|
||||
import type { TracePropagationOptions } from './types'
|
||||
|
||||
type Fetch = typeof fetch
|
||||
|
||||
export const resolveFetch = (customFetch?: Fetch): Fetch => {
|
||||
if (customFetch) {
|
||||
return (...args: Parameters<Fetch>) => customFetch(...args)
|
||||
}
|
||||
return (...args: Parameters<Fetch>) => fetch(...args)
|
||||
}
|
||||
|
||||
export const resolveHeadersConstructor = () => {
|
||||
return Headers
|
||||
}
|
||||
|
||||
/**
|
||||
* New-format Supabase API keys (`sb_publishable_…` / `sb_secret_…`) are not JWTs and
|
||||
* must never be sent as a Bearer token — they belong only in the `apikey` header.
|
||||
* All other keys (legacy JWT keys, `sb_temp_…` temporary keys, unrecognized `sb_`
|
||||
* subtypes) keep the Bearer fallback.
|
||||
*/
|
||||
const isNewApiKey = (key: string): boolean =>
|
||||
key.startsWith('sb_publishable_') || key.startsWith('sb_secret_')
|
||||
|
||||
const TEMP_KEY_PREFIX = 'sb_temp_'
|
||||
|
||||
const warnedKeySubtypes = new Set<string>()
|
||||
|
||||
/**
|
||||
* Warn (once per subtype) when an `sb_` key isn't a subtype this SDK version recognizes.
|
||||
* Never throws — the server, not the SDK, decides key validity. The key value is never
|
||||
* included in the message.
|
||||
*/
|
||||
export const checkApiKeyFormat = (key: string): void => {
|
||||
if (!key.startsWith('sb_') || isNewApiKey(key) || key.startsWith(TEMP_KEY_PREFIX)) {
|
||||
return
|
||||
}
|
||||
const subtype = key.match(/^sb_[a-zA-Z0-9]+_/)?.[0] ?? 'unknown'
|
||||
if (warnedKeySubtypes.has(subtype)) {
|
||||
return
|
||||
}
|
||||
warnedKeySubtypes.add(subtype)
|
||||
console.warn(
|
||||
'@supabase/supabase-js: Unrecognized Supabase API key format. The client will proceed ' +
|
||||
'and send this key as-is; if you see authentication errors you may need to upgrade ' +
|
||||
'@supabase/supabase-js to a version that recognizes this key type.'
|
||||
)
|
||||
}
|
||||
|
||||
export const fetchWithAuth = (
|
||||
supabaseKey: string,
|
||||
supabaseUrl: string,
|
||||
getAccessToken: () => Promise<string | null>,
|
||||
customFetch?: Fetch,
|
||||
tracePropagationOptions?: TracePropagationOptions,
|
||||
options?: { omitApiKeyAsBearer?: boolean }
|
||||
): Fetch => {
|
||||
const fetch = resolveFetch(customFetch)
|
||||
const HeadersConstructor = resolveHeadersConstructor()
|
||||
|
||||
// Pre-compute trace propagation state once. When disabled, the per-request
|
||||
// path skips all tracing work with a single truthy check.
|
||||
const traceEnabled = tracePropagationOptions?.enabled === true
|
||||
const respectSampling = tracePropagationOptions?.respectSamplingDecision !== false
|
||||
const traceTargets: TracePropagationTarget[] | null = traceEnabled
|
||||
? getDefaultPropagationTargets(supabaseUrl)
|
||||
: null
|
||||
|
||||
// Whether the API key may be used as the `Authorization` Bearer fallback when there is no
|
||||
// session token. Disabled for Edge Functions with a new-format key (see `isNewApiKey`).
|
||||
// Static per instance, so it is computed once here rather than on every request.
|
||||
const allowKeyAsBearer = !(options?.omitApiKeyAsBearer && isNewApiKey(supabaseKey))
|
||||
|
||||
return async (input, init) => {
|
||||
const realToken = await getAccessToken()
|
||||
let headers = new HeadersConstructor(init?.headers)
|
||||
|
||||
if (!headers.has('apikey')) {
|
||||
headers.set('apikey', supabaseKey)
|
||||
}
|
||||
|
||||
if (!headers.has('Authorization')) {
|
||||
const bearer = realToken ?? (allowKeyAsBearer ? supabaseKey : null)
|
||||
if (bearer) {
|
||||
headers.set('Authorization', `Bearer ${bearer}`)
|
||||
}
|
||||
}
|
||||
|
||||
if (traceTargets) {
|
||||
const traceHeaders = await getTraceHeaders(input, traceTargets, respectSampling)
|
||||
|
||||
if (traceHeaders) {
|
||||
if (traceHeaders.traceparent && !headers.has('traceparent')) {
|
||||
headers.set('traceparent', traceHeaders.traceparent)
|
||||
}
|
||||
if (traceHeaders.tracestate && !headers.has('tracestate')) {
|
||||
headers.set('tracestate', traceHeaders.tracestate)
|
||||
}
|
||||
if (traceHeaders.baggage && !headers.has('baggage')) {
|
||||
headers.set('baggage', traceHeaders.baggage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fetch(input, { ...init, headers })
|
||||
}
|
||||
}
|
||||
|
||||
async function getTraceHeaders(
|
||||
input: RequestInfo | URL,
|
||||
targets: TracePropagationTarget[],
|
||||
respectSampling: boolean
|
||||
): Promise<TraceContext | null> {
|
||||
const targetUrl: string | URL =
|
||||
typeof input === 'string' ? input : input instanceof URL ? input : input.url
|
||||
|
||||
if (!shouldPropagateToTarget(targetUrl, targets)) {
|
||||
return null
|
||||
}
|
||||
|
||||
const traceContext = await extractTraceContext()
|
||||
|
||||
if (!traceContext || !traceContext.traceparent) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (respectSampling) {
|
||||
const parsed = parseTraceParent(traceContext.traceparent)
|
||||
if (parsed && !parsed.isSampled) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
return traceContext
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
// helpers.ts
|
||||
import { SupabaseClientOptions, TracePropagationOptions } from './types'
|
||||
|
||||
function normalizeTracePropagation(
|
||||
value: TracePropagationOptions | boolean | undefined
|
||||
): TracePropagationOptions | undefined {
|
||||
return typeof value === 'boolean' ? { enabled: value } : value
|
||||
}
|
||||
|
||||
export function uuid() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = (Math.random() * 16) | 0,
|
||||
v = c == 'x' ? r : (r & 0x3) | 0x8
|
||||
return v.toString(16)
|
||||
})
|
||||
}
|
||||
|
||||
export function ensureTrailingSlash(url: string): string {
|
||||
return url.endsWith('/') ? url : url + '/'
|
||||
}
|
||||
|
||||
export const isBrowser = () => typeof window !== 'undefined'
|
||||
|
||||
export type ResolvedSupabaseClientOptions<SchemaName> = Omit<
|
||||
Required<SupabaseClientOptions<SchemaName>>,
|
||||
'tracePropagation'
|
||||
> & {
|
||||
tracePropagation: TracePropagationOptions
|
||||
}
|
||||
|
||||
export function applySettingDefaults<
|
||||
Database = any,
|
||||
SchemaName extends string & keyof Database = 'public' extends keyof Database
|
||||
? 'public'
|
||||
: string & keyof Database,
|
||||
>(
|
||||
options: SupabaseClientOptions<SchemaName>,
|
||||
defaults: SupabaseClientOptions<any>
|
||||
): ResolvedSupabaseClientOptions<SchemaName> {
|
||||
const {
|
||||
db: dbOptions,
|
||||
auth: authOptions,
|
||||
realtime: realtimeOptions,
|
||||
global: globalOptions,
|
||||
} = options
|
||||
const {
|
||||
db: DEFAULT_DB_OPTIONS,
|
||||
auth: DEFAULT_AUTH_OPTIONS,
|
||||
realtime: DEFAULT_REALTIME_OPTIONS,
|
||||
global: DEFAULT_GLOBAL_OPTIONS,
|
||||
} = defaults
|
||||
|
||||
// Accept either a boolean shorthand or an options object on both sides.
|
||||
const tracePropagationOptions = normalizeTracePropagation(options.tracePropagation)
|
||||
const DEFAULT_TRACE_PROPAGATION_OPTIONS = normalizeTracePropagation(defaults.tracePropagation)
|
||||
|
||||
const result: ResolvedSupabaseClientOptions<SchemaName> = {
|
||||
db: {
|
||||
...DEFAULT_DB_OPTIONS,
|
||||
...dbOptions,
|
||||
},
|
||||
auth: {
|
||||
...DEFAULT_AUTH_OPTIONS,
|
||||
...authOptions,
|
||||
},
|
||||
realtime: {
|
||||
...DEFAULT_REALTIME_OPTIONS,
|
||||
...realtimeOptions,
|
||||
},
|
||||
storage: {},
|
||||
global: {
|
||||
...DEFAULT_GLOBAL_OPTIONS,
|
||||
...globalOptions,
|
||||
headers: {
|
||||
...(DEFAULT_GLOBAL_OPTIONS?.headers ?? {}),
|
||||
...(globalOptions?.headers ?? {}),
|
||||
},
|
||||
},
|
||||
tracePropagation: {
|
||||
enabled:
|
||||
tracePropagationOptions?.enabled ?? DEFAULT_TRACE_PROPAGATION_OPTIONS?.enabled ?? false,
|
||||
respectSamplingDecision:
|
||||
tracePropagationOptions?.respectSamplingDecision ??
|
||||
DEFAULT_TRACE_PROPAGATION_OPTIONS?.respectSamplingDecision ??
|
||||
true,
|
||||
},
|
||||
accessToken: async () => '',
|
||||
}
|
||||
|
||||
if (options.accessToken) {
|
||||
result.accessToken = options.accessToken
|
||||
} else {
|
||||
// hack around Required<>
|
||||
delete (result as any).accessToken
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a Supabase client URL
|
||||
*
|
||||
* @param {string} supabaseUrl - The Supabase client URL string.
|
||||
* @returns {URL} - The validated base URL.
|
||||
* @throws {Error}
|
||||
*/
|
||||
export function validateSupabaseUrl(supabaseUrl: string): URL {
|
||||
const trimmedUrl = supabaseUrl?.trim()
|
||||
|
||||
if (!trimmedUrl) {
|
||||
throw new Error('supabaseUrl is required.')
|
||||
}
|
||||
|
||||
if (!trimmedUrl.match(/^https?:\/\//i)) {
|
||||
throw new Error('Invalid supabaseUrl: Must be a valid HTTP or HTTPS URL.')
|
||||
}
|
||||
|
||||
try {
|
||||
return new URL(ensureTrailingSlash(trimmedUrl))
|
||||
} catch {
|
||||
throw Error('Invalid supabaseUrl: Provided URL is malformed.')
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* AUTO-GENERATED FILE - DO NOT EDIT
|
||||
*
|
||||
* This file is automatically synchronized from @supabase/postgrest-js
|
||||
* Source: packages/core/postgrest-js/src/types/common/
|
||||
*
|
||||
* To update this file, modify the source in postgrest-js and run:
|
||||
* pnpm run codegen
|
||||
*/
|
||||
|
||||
// Types that are shared between supabase-js and postgrest-js
|
||||
|
||||
export type Fetch = typeof fetch
|
||||
|
||||
/**
|
||||
* Default number of retry attempts.
|
||||
*/
|
||||
export const DEFAULT_MAX_RETRIES = 3
|
||||
|
||||
/**
|
||||
* Default exponential backoff delay function.
|
||||
* Delays: 1s, 2s, 4s, 8s, ... (max 30s)
|
||||
*
|
||||
* @param attemptIndex - Zero-based index of the retry attempt
|
||||
* @returns Delay in milliseconds before the next retry
|
||||
*/
|
||||
export const getRetryDelay = (attemptIndex: number): number =>
|
||||
Math.min(1000 * 2 ** attemptIndex, 30000)
|
||||
|
||||
/**
|
||||
* Status codes that are safe to retry.
|
||||
* 520 = Cloudflare timeout/connection errors (transient)
|
||||
* 503 = PostgREST schema cache not yet loaded (transient, signals retry via Retry-After header)
|
||||
*/
|
||||
export const RETRYABLE_STATUS_CODES = [520, 503] as const
|
||||
|
||||
/**
|
||||
* HTTP methods that are safe to retry (idempotent operations).
|
||||
*/
|
||||
export const RETRYABLE_METHODS = ['GET', 'HEAD', 'OPTIONS'] as const
|
||||
|
||||
export type GenericRelationship = {
|
||||
foreignKeyName: string
|
||||
columns: string[]
|
||||
isOneToOne?: boolean
|
||||
referencedRelation: string
|
||||
referencedColumns: string[]
|
||||
}
|
||||
|
||||
export type GenericTable = {
|
||||
Row: Record<string, unknown>
|
||||
Insert: Record<string, unknown>
|
||||
Update: Record<string, unknown>
|
||||
Relationships: GenericRelationship[]
|
||||
}
|
||||
|
||||
export type GenericUpdatableView = {
|
||||
Row: Record<string, unknown>
|
||||
Insert: Record<string, unknown>
|
||||
Update: Record<string, unknown>
|
||||
Relationships: GenericRelationship[]
|
||||
}
|
||||
|
||||
export type GenericNonUpdatableView = {
|
||||
Row: Record<string, unknown>
|
||||
Relationships: GenericRelationship[]
|
||||
}
|
||||
|
||||
export type GenericView = GenericUpdatableView | GenericNonUpdatableView
|
||||
|
||||
export type GenericSetofOption = {
|
||||
isSetofReturn?: boolean | undefined
|
||||
isOneToOne?: boolean | undefined
|
||||
isNotNullable?: boolean | undefined
|
||||
to: string
|
||||
from: string
|
||||
}
|
||||
|
||||
export type GenericFunction = {
|
||||
Args: Record<string, unknown> | never
|
||||
Returns: unknown
|
||||
SetofOptions?: GenericSetofOption
|
||||
}
|
||||
|
||||
export type GenericSchema = {
|
||||
Tables: Record<string, GenericTable>
|
||||
Views: Record<string, GenericView>
|
||||
Functions: Record<string, GenericFunction>
|
||||
}
|
||||
|
||||
export type ClientServerOptions = {
|
||||
PostgrestVersion?: string
|
||||
}
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* AUTO-GENERATED FILE - DO NOT EDIT
|
||||
*
|
||||
* This file is automatically synchronized from @supabase/postgrest-js
|
||||
* Source: packages/core/postgrest-js/src/types/common/
|
||||
*
|
||||
* To update this file, modify the source in postgrest-js and run:
|
||||
* pnpm run codegen
|
||||
*/
|
||||
|
||||
import type { GenericFunction, GenericSchema, GenericSetofOption } from './common'
|
||||
|
||||
// Functions matching utils
|
||||
type IsMatchingArgs<
|
||||
FnArgs extends GenericFunction['Args'],
|
||||
PassedArgs extends GenericFunction['Args'],
|
||||
> = [FnArgs] extends [Record<PropertyKey, never>]
|
||||
? PassedArgs extends Record<PropertyKey, never>
|
||||
? true
|
||||
: false
|
||||
: keyof PassedArgs extends keyof FnArgs
|
||||
? PassedArgs extends FnArgs
|
||||
? true
|
||||
: false
|
||||
: false
|
||||
|
||||
type MatchingFunctionArgs<
|
||||
Fn extends GenericFunction,
|
||||
Args extends GenericFunction['Args'],
|
||||
> = Fn extends { Args: infer A extends GenericFunction['Args'] }
|
||||
? IsMatchingArgs<A, Args> extends true
|
||||
? Fn
|
||||
: never
|
||||
: false
|
||||
|
||||
type FindMatchingFunctionByArgs<
|
||||
FnUnion,
|
||||
Args extends GenericFunction['Args'],
|
||||
> = FnUnion extends infer Fn extends GenericFunction ? MatchingFunctionArgs<Fn, Args> : false
|
||||
|
||||
// Types for working with database schemas
|
||||
type TablesAndViews<Schema extends GenericSchema> = Schema['Tables'] & Exclude<Schema['Views'], ''>
|
||||
|
||||
// Utility types for working with unions
|
||||
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void
|
||||
? I
|
||||
: never
|
||||
|
||||
type LastOf<T> =
|
||||
UnionToIntersection<T extends any ? () => T : never> extends () => infer R ? R : never
|
||||
|
||||
type IsAny<T> = 0 extends 1 & T ? true : false
|
||||
|
||||
type ExactMatch<T, S> = [T] extends [S] ? ([S] extends [T] ? true : false) : false
|
||||
|
||||
type ExtractExactFunction<Fns, Args> = Fns extends infer F
|
||||
? F extends GenericFunction
|
||||
? ExactMatch<F['Args'], Args> extends true
|
||||
? F
|
||||
: never
|
||||
: never
|
||||
: never
|
||||
|
||||
type IsNever<T> = [T] extends [never] ? true : false
|
||||
|
||||
type RpcFunctionNotFound<FnName> = {
|
||||
Row: any
|
||||
Result: {
|
||||
error: true
|
||||
} & "Couldn't infer function definition matching provided arguments"
|
||||
RelationName: FnName
|
||||
Relationships: null
|
||||
}
|
||||
|
||||
type CrossSchemaError<TableRef extends string> = {
|
||||
error: true
|
||||
} & `Function returns SETOF from a different schema ('${TableRef}'). Use .overrideTypes<YourReturnType>() to specify the return type explicitly.`
|
||||
|
||||
export type GetRpcFunctionFilterBuilderByArgs<
|
||||
Schema extends GenericSchema,
|
||||
FnName extends string & keyof Schema['Functions'],
|
||||
Args,
|
||||
> = {
|
||||
0: Schema['Functions'][FnName]
|
||||
// If the Args is exactly never (function call without any params)
|
||||
1: IsAny<Schema> extends true
|
||||
? any
|
||||
: IsNever<Args> extends true
|
||||
? // This is for retro compatibility, if the funcition is defined with an single return and an union of Args
|
||||
// we fallback to the last function definition matched by name
|
||||
IsNever<ExtractExactFunction<Schema['Functions'][FnName], Args>> extends true
|
||||
? LastOf<Schema['Functions'][FnName]>
|
||||
: ExtractExactFunction<Schema['Functions'][FnName], Args>
|
||||
: Args extends Record<PropertyKey, never>
|
||||
? LastOf<Schema['Functions'][FnName]>
|
||||
: // Otherwise, we attempt to match with one of the function definition in the union based
|
||||
// on the function arguments provided
|
||||
Args extends GenericFunction['Args']
|
||||
? // This is for retro compatibility, if the funcition is defined with an single return and an union of Args
|
||||
// we fallback to the last function definition matched by name
|
||||
IsNever<
|
||||
LastOf<FindMatchingFunctionByArgs<Schema['Functions'][FnName], Args>>
|
||||
> extends true
|
||||
? LastOf<Schema['Functions'][FnName]>
|
||||
: // Otherwise, we use the arguments based function definition narrowing to get the right value
|
||||
LastOf<FindMatchingFunctionByArgs<Schema['Functions'][FnName], Args>>
|
||||
: // If we can't find a matching function by args, we try to find one by function name
|
||||
ExtractExactFunction<Schema['Functions'][FnName], Args> extends GenericFunction
|
||||
? ExtractExactFunction<Schema['Functions'][FnName], Args>
|
||||
: any
|
||||
}[1] extends infer Fn
|
||||
? // If we are dealing with an non-typed client everything is any
|
||||
IsAny<Fn> extends true
|
||||
? { Row: any; Result: any; RelationName: FnName; Relationships: null }
|
||||
: // Otherwise, we use the arguments based function definition narrowing to get the right value
|
||||
Fn extends GenericFunction
|
||||
? {
|
||||
Row: Fn['SetofOptions'] extends GenericSetofOption
|
||||
? Fn['SetofOptions']['to'] extends keyof TablesAndViews<Schema>
|
||||
? TablesAndViews<Schema>[Fn['SetofOptions']['to']]['Row']
|
||||
: // Cross-schema fallback: use Returns type when table is not in current schema
|
||||
Fn['Returns'] extends any[]
|
||||
? Fn['Returns'][number] extends Record<string, unknown>
|
||||
? Fn['Returns'][number]
|
||||
: CrossSchemaError<Fn['SetofOptions']['to'] & string>
|
||||
: Fn['Returns'] extends Record<string, unknown>
|
||||
? Fn['Returns']
|
||||
: CrossSchemaError<Fn['SetofOptions']['to'] & string>
|
||||
: Fn['Returns'] extends any[]
|
||||
? Fn['Returns'][number] extends Record<string, unknown>
|
||||
? Fn['Returns'][number]
|
||||
: never
|
||||
: Fn['Returns'] extends Record<string, unknown>
|
||||
? Fn['Returns']
|
||||
: never
|
||||
Result: Fn['SetofOptions'] extends GenericSetofOption
|
||||
? Fn['SetofOptions']['isSetofReturn'] extends true
|
||||
? Fn['SetofOptions']['isOneToOne'] extends true
|
||||
? Fn['Returns'][]
|
||||
: Fn['Returns']
|
||||
: Fn['Returns']
|
||||
: Fn['Returns']
|
||||
RelationName: Fn['SetofOptions'] extends GenericSetofOption
|
||||
? Fn['SetofOptions']['to']
|
||||
: FnName
|
||||
Relationships: Fn['SetofOptions'] extends GenericSetofOption
|
||||
? Fn['SetofOptions']['to'] extends keyof Schema['Tables']
|
||||
? Schema['Tables'][Fn['SetofOptions']['to']]['Relationships']
|
||||
: Fn['SetofOptions']['to'] extends keyof Schema['Views']
|
||||
? Schema['Views'][Fn['SetofOptions']['to']]['Relationships']
|
||||
: null
|
||||
: null
|
||||
}
|
||||
: // If we failed to find the function by argument, we still pass with any but also add an overridable
|
||||
Fn extends false
|
||||
? RpcFunctionNotFound<FnName>
|
||||
: RpcFunctionNotFound<FnName>
|
||||
: RpcFunctionNotFound<FnName>
|
||||
+320
@@ -0,0 +1,320 @@
|
||||
import { GoTrueClientOptions } from '@supabase/auth-js'
|
||||
import { RealtimeClientOptions } from '@supabase/realtime-js'
|
||||
import { PostgrestError } from '@supabase/postgrest-js'
|
||||
import type { StorageClientOptions } from '@supabase/storage-js'
|
||||
import type {
|
||||
GenericSchema,
|
||||
GenericRelationship,
|
||||
GenericTable,
|
||||
GenericUpdatableView,
|
||||
GenericNonUpdatableView,
|
||||
GenericView,
|
||||
GenericFunction,
|
||||
} from './rest/types/common/common'
|
||||
export type {
|
||||
GenericSchema,
|
||||
GenericRelationship,
|
||||
GenericTable,
|
||||
GenericUpdatableView,
|
||||
GenericNonUpdatableView,
|
||||
GenericView,
|
||||
GenericFunction,
|
||||
}
|
||||
|
||||
export interface SupabaseAuthClientOptions extends GoTrueClientOptions {}
|
||||
|
||||
export type Fetch = typeof fetch
|
||||
|
||||
/**
|
||||
* Configuration options for trace context propagation.
|
||||
*
|
||||
* Enables distributed tracing across Supabase services using W3C Trace Context
|
||||
* and OpenTelemetry standards. When enabled, the SDK automatically attaches
|
||||
* trace context headers (`traceparent`, `tracestate`, `baggage`) to outgoing
|
||||
* requests to Supabase domains. The resulting `trace_id` appears in API
|
||||
* Gateway and Edge Function logs, so logs forwarded through Log Drains can
|
||||
* be correlated back to the originating client-side span.
|
||||
*
|
||||
* Requires `@opentelemetry/api` to be installed in the consuming application.
|
||||
* If it is not installed, or there is no active context at request time,
|
||||
* propagation silently no-ops.
|
||||
*
|
||||
* @example Enable with defaults
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* tracePropagation: { enabled: true },
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @see https://www.w3.org/TR/trace-context/
|
||||
* @see https://opentelemetry.io/docs/concepts/context-propagation/
|
||||
* @see https://supabase.com/docs/guides/telemetry/client-side-tracing
|
||||
*/
|
||||
export interface TracePropagationOptions {
|
||||
/**
|
||||
* Enable trace propagation. Disabled by default.
|
||||
*
|
||||
* When enabled, automatically detects and propagates active trace context
|
||||
* from the OpenTelemetry API to outgoing Supabase requests. Trace context
|
||||
* is only propagated to Supabase domains (`*.supabase.co`, `*.supabase.in`,
|
||||
* `localhost`) for security — third-party hosts never receive trace headers.
|
||||
*
|
||||
* @default false
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* tracePropagation: { enabled: true },
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
enabled?: boolean
|
||||
|
||||
/**
|
||||
* Respect upstream sampling decisions.
|
||||
*
|
||||
* When true (the default), trace context is not propagated if the upstream
|
||||
* trace indicates non-sampling (sampled flag = `0` in the `traceparent`
|
||||
* header). This avoids overhead when traces are being recorded but dropped.
|
||||
*
|
||||
* Set to `false` to always propagate, regardless of the sampling decision
|
||||
* — useful when you want every Supabase request tagged with a `trace_id`
|
||||
* for log correlation, even if the trace itself will not be exported.
|
||||
*
|
||||
* @default true
|
||||
*
|
||||
* @example Always propagate, ignore sampling
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* tracePropagation: { enabled: true, respectSamplingDecision: false },
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
respectSamplingDecision?: boolean
|
||||
}
|
||||
|
||||
export type SupabaseClientOptions<SchemaName> = {
|
||||
/**
|
||||
* The Postgres schema which your tables belong to. Must be on the list of exposed schemas in Supabase. Defaults to `public`.
|
||||
*/
|
||||
db?: {
|
||||
schema?: SchemaName
|
||||
/**
|
||||
* Optional timeout in milliseconds for PostgREST requests.
|
||||
* When set, requests will automatically abort after this duration to prevent indefinite hangs.
|
||||
*
|
||||
* @example With timeout
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* db: { timeout: 30000 } // 30 second timeout
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
timeout?: number
|
||||
/**
|
||||
* Maximum URL length in characters before warnings/errors are triggered.
|
||||
* Defaults to 8000 characters. Used to provide helpful hints when URLs
|
||||
* exceed server limits.
|
||||
*
|
||||
* @example With custom URL length limit
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* db: { urlLengthLimit: 10000 } // Custom limit
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
urlLengthLimit?: number
|
||||
}
|
||||
|
||||
auth?: {
|
||||
/**
|
||||
* Automatically refreshes the token for logged-in users. Defaults to true.
|
||||
*/
|
||||
autoRefreshToken?: boolean
|
||||
/**
|
||||
* Optional key name used for storing tokens in local storage.
|
||||
*/
|
||||
storageKey?: string
|
||||
/**
|
||||
* Whether to persist a logged-in session to storage. Defaults to true.
|
||||
*/
|
||||
persistSession?: boolean
|
||||
/**
|
||||
* Detect a session from the URL. Used for OAuth login callbacks. Defaults to true.
|
||||
*
|
||||
* Can be set to a function to provide custom logic for determining if a URL contains
|
||||
* a Supabase auth callback. The function receives the current URL and parsed parameters,
|
||||
* and should return true if the URL should be processed as a Supabase auth callback.
|
||||
*
|
||||
* This is useful when your app uses other OAuth providers (e.g., Facebook Login) that
|
||||
* also return access_token in the URL fragment, which would otherwise be incorrectly
|
||||
* intercepted by Supabase Auth.
|
||||
*
|
||||
* @example With custom detection logic
|
||||
* ```ts
|
||||
* detectSessionInUrl: (url, params) => {
|
||||
* // Ignore Facebook OAuth redirects
|
||||
* if (url.pathname === '/facebook/redirect') return false
|
||||
* // Use default detection for other URLs
|
||||
* return Boolean(params.access_token || params.error_description)
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
detectSessionInUrl?: boolean | ((url: URL, params: { [parameter: string]: string }) => boolean)
|
||||
/**
|
||||
* A storage provider. Used to store the logged-in session.
|
||||
*/
|
||||
storage?: SupabaseAuthClientOptions['storage']
|
||||
/**
|
||||
* A storage provider to store the user profile separately from the session.
|
||||
* Useful when you need to store the session information in cookies,
|
||||
* without bloating the data with the redundant user object.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
userStorage?: SupabaseAuthClientOptions['userStorage']
|
||||
/**
|
||||
* OAuth flow to use - defaults to implicit flow. PKCE is recommended for mobile and server-side applications.
|
||||
*/
|
||||
flowType?: SupabaseAuthClientOptions['flowType']
|
||||
/**
|
||||
* If debug messages for authentication client are emitted. Can be used to inspect the behavior of the library.
|
||||
*/
|
||||
debug?: SupabaseAuthClientOptions['debug']
|
||||
/**
|
||||
* Provide your own locking mechanism based on the environment. By default
|
||||
* the auth client coordinates refreshes itself and the server resolves
|
||||
* cross-tab races. Passing a custom `lock` opts into a legacy path that
|
||||
* wraps every auth operation in your supplied lock.
|
||||
*
|
||||
* @deprecated Custom locks still work in v2.x for backwards compatibility.
|
||||
* The legacy lock path will be removed in v3 — drop this option from your
|
||||
* `createClient` options before upgrading.
|
||||
*/
|
||||
lock?: SupabaseAuthClientOptions['lock']
|
||||
/**
|
||||
* If there is an error with the query, throwOnError will reject the promise by
|
||||
* throwing the error instead of returning it as part of a successful response.
|
||||
*/
|
||||
throwOnError?: SupabaseAuthClientOptions['throwOnError']
|
||||
/**
|
||||
* Opt-in flags for experimental features. These APIs may change without
|
||||
* notice and are disabled by default.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
experimental?: SupabaseAuthClientOptions['experimental']
|
||||
/**
|
||||
* Maximum time in milliseconds to wait for acquiring the custom lock
|
||||
* supplied via `lock`. Only consulted when a custom `lock` is passed.
|
||||
*
|
||||
* @default 5000
|
||||
*
|
||||
* @deprecated Only used by the legacy lock path. Will be removed in v3
|
||||
* along with the `lock` option.
|
||||
*/
|
||||
lockAcquireTimeout?: SupabaseAuthClientOptions['lockAcquireTimeout']
|
||||
/**
|
||||
* If true, skips automatic initialization in the auth client constructor.
|
||||
* Useful for SSR contexts where initialization timing must be controlled to
|
||||
* prevent race conditions with HTTP response generation.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
skipAutoInitialize?: SupabaseAuthClientOptions['skipAutoInitialize']
|
||||
}
|
||||
/**
|
||||
* Options passed to the realtime-js instance
|
||||
*/
|
||||
realtime?: RealtimeClientOptions
|
||||
storage?: StorageClientOptions
|
||||
global?: {
|
||||
/**
|
||||
* A custom `fetch` implementation.
|
||||
*/
|
||||
fetch?: Fetch
|
||||
/**
|
||||
* Optional headers for initializing the client.
|
||||
*/
|
||||
headers?: Record<string, string>
|
||||
}
|
||||
/**
|
||||
* Optional function for using a third-party authentication system with
|
||||
* Supabase. The function should return an access token or ID token (JWT) by
|
||||
* obtaining it from the third-party auth SDK. Note that this
|
||||
* function may be called concurrently and many times. Use memoization and
|
||||
* locking techniques if this is not supported by the SDKs.
|
||||
*
|
||||
* When set, the `auth` namespace of the Supabase client cannot be used.
|
||||
* Create another client if you wish to use Supabase Auth and third-party
|
||||
* authentications concurrently in the same application.
|
||||
*/
|
||||
accessToken?: () => Promise<string | null>
|
||||
/**
|
||||
* Enable OpenTelemetry / W3C trace context propagation to Supabase services.
|
||||
*
|
||||
* Disabled by default. Pass `true` for the common case (auto-detect an
|
||||
* active OpenTelemetry context and inject `traceparent` / `tracestate` /
|
||||
* `baggage` headers) or an object for fine-grained control.
|
||||
*
|
||||
* Requires `@opentelemetry/api` to be installed in your application; if
|
||||
* not present, the SDK silently no-ops. Trace headers are only attached
|
||||
* to requests targeting Supabase domains, so third-party hosts called
|
||||
* through a custom `fetch` are never tagged.
|
||||
*
|
||||
* The resulting `trace_id` appears in Supabase logs (API Gateway, Edge
|
||||
* Functions), letting you correlate client-side spans with server-side
|
||||
* log entries — including logs forwarded via Log Drains.
|
||||
*
|
||||
* @example Shorthand — opt in with defaults
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
*
|
||||
* const supabase = createClient(url, key, { tracePropagation: true })
|
||||
* ```
|
||||
*
|
||||
* @example With an active OpenTelemetry span
|
||||
* ```ts
|
||||
* import { createClient } from '@supabase/supabase-js'
|
||||
* import { trace } from '@opentelemetry/api'
|
||||
*
|
||||
* const supabase = createClient(url, key, { tracePropagation: true })
|
||||
* const tracer = trace.getTracer('my-app')
|
||||
*
|
||||
* await tracer.startActiveSpan('fetch-users', async (span) => {
|
||||
* // Request carries the active trace context.
|
||||
* const { data, error } = await supabase.from('users').select('*')
|
||||
* span.end()
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @example Advanced — always propagate, even for non-sampled traces
|
||||
* ```ts
|
||||
* const supabase = createClient(url, key, {
|
||||
* tracePropagation: { enabled: true, respectSamplingDecision: false },
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @see https://supabase.com/docs/guides/telemetry/client-side-tracing
|
||||
* @see https://www.w3.org/TR/trace-context/
|
||||
*/
|
||||
tracePropagation?: TracePropagationOptions | boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper types for query results.
|
||||
*/
|
||||
export type QueryResult<T> = T extends PromiseLike<infer U> ? U : never
|
||||
export type QueryData<T> = T extends PromiseLike<{ data: infer U }> ? Exclude<U, null> : never
|
||||
export type QueryError = PostgrestError
|
||||
|
||||
/**
|
||||
* Strips internal Supabase metadata from Database types.
|
||||
* Useful for libraries defining generic constraints on Database types.
|
||||
*
|
||||
* @example Stripping internal Supabase metadata
|
||||
* ```typescript
|
||||
* type CleanDB = DatabaseWithoutInternals<Database>
|
||||
* ```
|
||||
*/
|
||||
export type DatabaseWithoutInternals<DB> = Omit<DB, '__InternalSupabase'>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Generated automatically during releases by scripts/update-version-files.ts
|
||||
// This file provides runtime access to the package version for:
|
||||
// - HTTP request headers (e.g., X-Client-Info header for API requests)
|
||||
// - Debugging and support (identifying which version is running)
|
||||
// - Telemetry and logging (version reporting in errors/analytics)
|
||||
// - Ensuring build artifacts match the published package version
|
||||
export const version = '2.110.8'
|
||||
Reference in New Issue
Block a user