UNPKG

@supabase/supabase-js

Version:
405 lines (390 loc) 16.4 kB
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 { 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.88.0"; //#endregion //#region src/lib/constants.ts let JS_ENV = ""; if (typeof Deno !== "undefined") JS_ENV = "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 DEFAULT_HEADERS = { "X-Client-Info": `supabase-js-${JS_ENV}/${version}` }; 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 = {}; //#endregion //#region \0@oxc-project+runtime@0.101.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.101.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.101.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.101.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.101.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; }; const fetchWithAuth = (supabaseKey, getAccessToken, customFetch) => { const fetch$1 = resolveFetch(customFetch); const HeadersConstructor = resolveHeadersConstructor(); return async (input, init) => { var _await$getAccessToken; const accessToken = (_await$getAccessToken = await getAccessToken()) !== null && _await$getAccessToken !== void 0 ? _await$getAccessToken : supabaseKey; 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")) headers.set("Authorization", `Bearer ${accessToken}`); return fetch$1(input, _objectSpread2(_objectSpread2({}, init), {}, { headers })); }; }; //#endregion //#region src/lib/helpers.ts function ensureTrailingSlash(url) { return url.endsWith("/") ? url : url + "/"; } function applySettingDefaults(options, defaults) { var _DEFAULT_GLOBAL_OPTIO, _globalOptions$header; 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 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 : {}) }), 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. * @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.db.schema You can switch in between schemas. The schema needs to be on the list of exposed schemas inside Supabase. * @param options.auth.autoRefreshToken Set to "true" if you want to automatically refresh the token before expiring. * @param options.auth.persistSession Set to "true" if you want to automatically save the user session into local storage. * @param options.auth.detectSessionInUrl Set to "true" if you want to automatically detects OAuth grants in the URL and signs in the user. * @param options.realtime Options passed along to realtime-js constructor. * @param options.storage Options passed along to the storage-js constructor. * @param options.global.fetch A custom fetch implementation. * @param options.global.headers Any additional headers to send with each network request. * @example * ```ts * import { createClient } from '@supabase/supabase-js' * * const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key') * const { data } = await supabase.from('profiles').select('*') * ``` */ 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."); 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 }; const settings = applySettingDefaults(options !== null && options !== void 0 ? options : {}, DEFAULTS); 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, this._getAccessToken.bind(this), settings.global.fetch); this.realtime = this._initRealtimeClient(_objectSpread2({ headers: this.headers, accessToken: this._getAccessToken.bind(this) }, settings.realtime)); if (this.accessToken) 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 }); 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.fetch }); } /** * 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. * */ channel(name, opts = { config: {} }) { return this.realtime.channel(name, opts); } /** * Returns all Realtime channels. */ getChannels() { return this.realtime.getChannels(); } /** * Unsubscribes and removes Realtime channel from Realtime client. * * @param {RealtimeChannel} channel - The name of the Realtime channel. * */ removeChannel(channel) { return this.realtime.removeChannel(channel); } /** * Unsubscribes and removes all Realtime channels from Realtime client. */ removeAllChannels() { return this.realtime.removeAllChannels(); } async _getAccessToken() { 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_ : _this.supabaseKey; } _initSupabaseAuthClient({ autoRefreshToken, persistSession, detectSessionInUrl, storage, userStorage, storageKey, flowType, lock, debug, throwOnError }, 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, fetch: fetch$1, 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") && 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 * ```ts * import { createClient } from '@supabase/supabase-js' * * const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-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") return false; if (typeof process === "undefined") 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) <= 18; } if (shouldShowDeprecationWarning()) console.warn("⚠️ Node.js 18 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 20 or later. For more information, visit: https://github.com/orgs/supabase/discussions/37217"); //#endregion export { FunctionRegion, FunctionsError, FunctionsFetchError, FunctionsHttpError, FunctionsRelayError, PostgrestError, SupabaseClient, createClient }; //# sourceMappingURL=index.mjs.map