@bbearai/react-native 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.js +538 -149
  2. package/dist/index.mjs +539 -150
  3. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -309,7 +309,7 @@ var PostgrestBuilder = class {
309
309
  * ```
310
310
  */
311
311
  constructor(builder) {
312
- var _builder$shouldThrowO, _builder$isMaybeSingl;
312
+ var _builder$shouldThrowO, _builder$isMaybeSingl, _builder$urlLengthLim;
313
313
  this.shouldThrowOnError = false;
314
314
  this.method = builder.method;
315
315
  this.url = builder.url;
@@ -319,6 +319,7 @@ var PostgrestBuilder = class {
319
319
  this.shouldThrowOnError = (_builder$shouldThrowO = builder.shouldThrowOnError) !== null && _builder$shouldThrowO !== void 0 ? _builder$shouldThrowO : false;
320
320
  this.signal = builder.signal;
321
321
  this.isMaybeSingle = (_builder$isMaybeSingl = builder.isMaybeSingle) !== null && _builder$isMaybeSingl !== void 0 ? _builder$isMaybeSingl : false;
322
+ this.urlLengthLimit = (_builder$urlLengthLim = builder.urlLengthLimit) !== null && _builder$urlLengthLim !== void 0 ? _builder$urlLengthLim : 8e3;
322
323
  if (builder.fetch) this.fetch = builder.fetch;
323
324
  else this.fetch = fetch;
324
325
  }
@@ -419,6 +420,8 @@ var PostgrestBuilder = class {
419
420
  if (!this.shouldThrowOnError) res = res.catch((fetchError) => {
420
421
  var _fetchError$name2;
421
422
  let errorDetails = "";
423
+ let hint = "";
424
+ let code = "";
422
425
  const cause = fetchError === null || fetchError === void 0 ? void 0 : fetchError.cause;
423
426
  if (cause) {
424
427
  var _cause$message, _cause$code, _fetchError$name, _cause$name;
@@ -435,12 +438,22 @@ ${cause.stack}`;
435
438
  var _fetchError$stack;
436
439
  errorDetails = (_fetchError$stack = fetchError === null || fetchError === void 0 ? void 0 : fetchError.stack) !== null && _fetchError$stack !== void 0 ? _fetchError$stack : "";
437
440
  }
441
+ const urlLength = this.url.toString().length;
442
+ if ((fetchError === null || fetchError === void 0 ? void 0 : fetchError.name) === "AbortError" || (fetchError === null || fetchError === void 0 ? void 0 : fetchError.code) === "ABORT_ERR") {
443
+ code = "";
444
+ hint = "Request was aborted (timeout or manual cancellation)";
445
+ if (urlLength > this.urlLengthLimit) hint += `. Note: Your request URL is ${urlLength} characters, which may exceed server limits. If selecting many fields, consider using views. If filtering with large arrays (e.g., .in('id', [many IDs])), consider using an RPC function to pass values server-side.`;
446
+ } else if ((cause === null || cause === void 0 ? void 0 : cause.name) === "HeadersOverflowError" || (cause === null || cause === void 0 ? void 0 : cause.code) === "UND_ERR_HEADERS_OVERFLOW") {
447
+ code = "";
448
+ hint = "HTTP headers exceeded server limits (typically 16KB)";
449
+ if (urlLength > this.urlLengthLimit) hint += `. Your request URL is ${urlLength} characters. If selecting many fields, consider using views. If filtering with large arrays (e.g., .in('id', [200+ IDs])), consider using an RPC function instead.`;
450
+ }
438
451
  return {
439
452
  error: {
440
453
  message: `${(_fetchError$name2 = fetchError === null || fetchError === void 0 ? void 0 : fetchError.name) !== null && _fetchError$name2 !== void 0 ? _fetchError$name2 : "FetchError"}: ${fetchError === null || fetchError === void 0 ? void 0 : fetchError.message}`,
441
454
  details: errorDetails,
442
- hint: "",
443
- code: ""
455
+ hint,
456
+ code
444
457
  },
445
458
  data: null,
446
459
  count: null,
@@ -1082,11 +1095,12 @@ var PostgrestQueryBuilder = class {
1082
1095
  * )
1083
1096
  * ```
1084
1097
  */
1085
- constructor(url, { headers = {}, schema, fetch: fetch$1 }) {
1098
+ constructor(url, { headers = {}, schema, fetch: fetch$1, urlLengthLimit = 8e3 }) {
1086
1099
  this.url = url;
1087
1100
  this.headers = new Headers(headers);
1088
1101
  this.schema = schema;
1089
1102
  this.fetch = fetch$1;
1103
+ this.urlLengthLimit = urlLengthLimit;
1090
1104
  }
1091
1105
  /**
1092
1106
  * Clone URL and headers to prevent shared state between operations.
@@ -1139,7 +1153,8 @@ var PostgrestQueryBuilder = class {
1139
1153
  url,
1140
1154
  headers,
1141
1155
  schema: this.schema,
1142
- fetch: this.fetch
1156
+ fetch: this.fetch,
1157
+ urlLengthLimit: this.urlLengthLimit
1143
1158
  });
1144
1159
  }
1145
1160
  /**
@@ -1187,7 +1202,8 @@ var PostgrestQueryBuilder = class {
1187
1202
  headers,
1188
1203
  schema: this.schema,
1189
1204
  body: values,
1190
- fetch: (_this$fetch = this.fetch) !== null && _this$fetch !== void 0 ? _this$fetch : fetch
1205
+ fetch: (_this$fetch = this.fetch) !== null && _this$fetch !== void 0 ? _this$fetch : fetch,
1206
+ urlLengthLimit: this.urlLengthLimit
1191
1207
  });
1192
1208
  }
1193
1209
  /**
@@ -1296,7 +1312,8 @@ var PostgrestQueryBuilder = class {
1296
1312
  headers,
1297
1313
  schema: this.schema,
1298
1314
  body: values,
1299
- fetch: (_this$fetch2 = this.fetch) !== null && _this$fetch2 !== void 0 ? _this$fetch2 : fetch
1315
+ fetch: (_this$fetch2 = this.fetch) !== null && _this$fetch2 !== void 0 ? _this$fetch2 : fetch,
1316
+ urlLengthLimit: this.urlLengthLimit
1300
1317
  });
1301
1318
  }
1302
1319
  /**
@@ -1331,7 +1348,8 @@ var PostgrestQueryBuilder = class {
1331
1348
  headers,
1332
1349
  schema: this.schema,
1333
1350
  body: values,
1334
- fetch: (_this$fetch3 = this.fetch) !== null && _this$fetch3 !== void 0 ? _this$fetch3 : fetch
1351
+ fetch: (_this$fetch3 = this.fetch) !== null && _this$fetch3 !== void 0 ? _this$fetch3 : fetch,
1352
+ urlLengthLimit: this.urlLengthLimit
1335
1353
  });
1336
1354
  }
1337
1355
  /**
@@ -1363,10 +1381,62 @@ var PostgrestQueryBuilder = class {
1363
1381
  url,
1364
1382
  headers,
1365
1383
  schema: this.schema,
1366
- fetch: (_this$fetch4 = this.fetch) !== null && _this$fetch4 !== void 0 ? _this$fetch4 : fetch
1384
+ fetch: (_this$fetch4 = this.fetch) !== null && _this$fetch4 !== void 0 ? _this$fetch4 : fetch,
1385
+ urlLengthLimit: this.urlLengthLimit
1367
1386
  });
1368
1387
  }
1369
1388
  };
1389
+ function _typeof(o) {
1390
+ "@babel/helpers - typeof";
1391
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
1392
+ return typeof o$1;
1393
+ } : function(o$1) {
1394
+ return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
1395
+ }, _typeof(o);
1396
+ }
1397
+ function toPrimitive(t, r) {
1398
+ if ("object" != _typeof(t) || !t) return t;
1399
+ var e = t[Symbol.toPrimitive];
1400
+ if (void 0 !== e) {
1401
+ var i = e.call(t, r || "default");
1402
+ if ("object" != _typeof(i)) return i;
1403
+ throw new TypeError("@@toPrimitive must return a primitive value.");
1404
+ }
1405
+ return ("string" === r ? String : Number)(t);
1406
+ }
1407
+ function toPropertyKey(t) {
1408
+ var i = toPrimitive(t, "string");
1409
+ return "symbol" == _typeof(i) ? i : i + "";
1410
+ }
1411
+ function _defineProperty(e, r, t) {
1412
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
1413
+ value: t,
1414
+ enumerable: true,
1415
+ configurable: true,
1416
+ writable: true
1417
+ }) : e[r] = t, e;
1418
+ }
1419
+ function ownKeys(e, r) {
1420
+ var t = Object.keys(e);
1421
+ if (Object.getOwnPropertySymbols) {
1422
+ var o = Object.getOwnPropertySymbols(e);
1423
+ r && (o = o.filter(function(r$1) {
1424
+ return Object.getOwnPropertyDescriptor(e, r$1).enumerable;
1425
+ })), t.push.apply(t, o);
1426
+ }
1427
+ return t;
1428
+ }
1429
+ function _objectSpread2(e) {
1430
+ for (var r = 1; r < arguments.length; r++) {
1431
+ var t = null != arguments[r] ? arguments[r] : {};
1432
+ r % 2 ? ownKeys(Object(t), true).forEach(function(r$1) {
1433
+ _defineProperty(e, r$1, t[r$1]);
1434
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r$1) {
1435
+ Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t, r$1));
1436
+ });
1437
+ }
1438
+ return e;
1439
+ }
1370
1440
  var PostgrestClient = class PostgrestClient2 {
1371
1441
  /**
1372
1442
  * Creates a PostgREST client.
@@ -1376,6 +1446,8 @@ var PostgrestClient = class PostgrestClient2 {
1376
1446
  * @param options.headers - Custom headers
1377
1447
  * @param options.schema - Postgres schema to switch to
1378
1448
  * @param options.fetch - Custom fetch
1449
+ * @param options.timeout - Optional timeout in milliseconds for all requests. When set, requests will automatically abort after this duration to prevent indefinite hangs.
1450
+ * @param options.urlLengthLimit - Maximum URL length in characters before warnings/errors are triggered. Defaults to 8000.
1379
1451
  * @example
1380
1452
  * ```ts
1381
1453
  * import PostgrestClient from '@supabase/postgrest-js'
@@ -1383,14 +1455,38 @@ var PostgrestClient = class PostgrestClient2 {
1383
1455
  * const postgrest = new PostgrestClient('https://xyzcompany.supabase.co/rest/v1', {
1384
1456
  * headers: { apikey: 'public-anon-key' },
1385
1457
  * schema: 'public',
1458
+ * timeout: 30000, // 30 second timeout
1386
1459
  * })
1387
1460
  * ```
1388
1461
  */
1389
- constructor(url, { headers = {}, schema, fetch: fetch$1 } = {}) {
1462
+ constructor(url, { headers = {}, schema, fetch: fetch$1, timeout, urlLengthLimit = 8e3 } = {}) {
1390
1463
  this.url = url;
1391
1464
  this.headers = new Headers(headers);
1392
1465
  this.schemaName = schema;
1393
- this.fetch = fetch$1;
1466
+ this.urlLengthLimit = urlLengthLimit;
1467
+ const originalFetch = fetch$1 !== null && fetch$1 !== void 0 ? fetch$1 : globalThis.fetch;
1468
+ if (timeout !== void 0 && timeout > 0) this.fetch = (input, init) => {
1469
+ const controller = new AbortController();
1470
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
1471
+ const existingSignal = init === null || init === void 0 ? void 0 : init.signal;
1472
+ if (existingSignal) {
1473
+ if (existingSignal.aborted) {
1474
+ clearTimeout(timeoutId);
1475
+ return originalFetch(input, init);
1476
+ }
1477
+ const abortHandler = () => {
1478
+ clearTimeout(timeoutId);
1479
+ controller.abort();
1480
+ };
1481
+ existingSignal.addEventListener("abort", abortHandler, { once: true });
1482
+ return originalFetch(input, _objectSpread2(_objectSpread2({}, init), {}, { signal: controller.signal })).finally(() => {
1483
+ clearTimeout(timeoutId);
1484
+ existingSignal.removeEventListener("abort", abortHandler);
1485
+ });
1486
+ }
1487
+ return originalFetch(input, _objectSpread2(_objectSpread2({}, init), {}, { signal: controller.signal })).finally(() => clearTimeout(timeoutId));
1488
+ };
1489
+ else this.fetch = originalFetch;
1394
1490
  }
1395
1491
  /**
1396
1492
  * Perform a query on a table or a view.
@@ -1402,7 +1498,8 @@ var PostgrestClient = class PostgrestClient2 {
1402
1498
  return new PostgrestQueryBuilder(new URL(`${this.url}/${relation}`), {
1403
1499
  headers: new Headers(this.headers),
1404
1500
  schema: this.schemaName,
1405
- fetch: this.fetch
1501
+ fetch: this.fetch,
1502
+ urlLengthLimit: this.urlLengthLimit
1406
1503
  });
1407
1504
  }
1408
1505
  /**
@@ -1416,7 +1513,8 @@ var PostgrestClient = class PostgrestClient2 {
1416
1513
  return new PostgrestClient2(this.url, {
1417
1514
  headers: this.headers,
1418
1515
  schema,
1419
- fetch: this.fetch
1516
+ fetch: this.fetch,
1517
+ urlLengthLimit: this.urlLengthLimit
1420
1518
  });
1421
1519
  }
1422
1520
  /**
@@ -1479,7 +1577,8 @@ var PostgrestClient = class PostgrestClient2 {
1479
1577
  headers,
1480
1578
  schema: this.schemaName,
1481
1579
  body,
1482
- fetch: (_this$fetch = this.fetch) !== null && _this$fetch !== void 0 ? _this$fetch : fetch
1580
+ fetch: (_this$fetch = this.fetch) !== null && _this$fetch !== void 0 ? _this$fetch : fetch,
1581
+ urlLengthLimit: this.urlLengthLimit
1483
1582
  });
1484
1583
  }
1485
1584
  };
@@ -1601,7 +1700,7 @@ Suggested solution: ${env.workaround}`;
1601
1700
  var websocket_factory_default = WebSocketFactory;
1602
1701
 
1603
1702
  // ../../node_modules/@supabase/realtime-js/dist/module/lib/version.js
1604
- var version = "2.93.2";
1703
+ var version = "2.95.3";
1605
1704
 
1606
1705
  // ../../node_modules/@supabase/realtime-js/dist/module/lib/constants.js
1607
1706
  var DEFAULT_VERSION = `realtime-js/${version}`;
@@ -3088,6 +3187,9 @@ Option 2: Install and provide the "ws" package:
3088
3187
  */
3089
3188
  async removeChannel(channel) {
3090
3189
  const status = await channel.unsubscribe();
3190
+ if (status === "ok") {
3191
+ this._remove(channel);
3192
+ }
3091
3193
  if (this.channels.length === 0) {
3092
3194
  this.disconnect();
3093
3195
  }
@@ -4256,37 +4358,37 @@ var isValidBucketName = (bucketName) => {
4256
4358
  if (bucketName.includes("/") || bucketName.includes("\\")) return false;
4257
4359
  return /^[\w!.\*'() &$@=;:+,?-]+$/.test(bucketName);
4258
4360
  };
4259
- function _typeof(o) {
4361
+ function _typeof2(o) {
4260
4362
  "@babel/helpers - typeof";
4261
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
4363
+ return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
4262
4364
  return typeof o$1;
4263
4365
  } : function(o$1) {
4264
4366
  return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
4265
- }, _typeof(o);
4367
+ }, _typeof2(o);
4266
4368
  }
4267
- function toPrimitive(t, r) {
4268
- if ("object" != _typeof(t) || !t) return t;
4369
+ function toPrimitive2(t, r) {
4370
+ if ("object" != _typeof2(t) || !t) return t;
4269
4371
  var e = t[Symbol.toPrimitive];
4270
4372
  if (void 0 !== e) {
4271
4373
  var i = e.call(t, r || "default");
4272
- if ("object" != _typeof(i)) return i;
4374
+ if ("object" != _typeof2(i)) return i;
4273
4375
  throw new TypeError("@@toPrimitive must return a primitive value.");
4274
4376
  }
4275
4377
  return ("string" === r ? String : Number)(t);
4276
4378
  }
4277
- function toPropertyKey(t) {
4278
- var i = toPrimitive(t, "string");
4279
- return "symbol" == _typeof(i) ? i : i + "";
4379
+ function toPropertyKey2(t) {
4380
+ var i = toPrimitive2(t, "string");
4381
+ return "symbol" == _typeof2(i) ? i : i + "";
4280
4382
  }
4281
- function _defineProperty(e, r, t) {
4282
- return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
4383
+ function _defineProperty2(e, r, t) {
4384
+ return (r = toPropertyKey2(r)) in e ? Object.defineProperty(e, r, {
4283
4385
  value: t,
4284
4386
  enumerable: true,
4285
4387
  configurable: true,
4286
4388
  writable: true
4287
4389
  }) : e[r] = t, e;
4288
4390
  }
4289
- function ownKeys(e, r) {
4391
+ function ownKeys2(e, r) {
4290
4392
  var t = Object.keys(e);
4291
4393
  if (Object.getOwnPropertySymbols) {
4292
4394
  var o = Object.getOwnPropertySymbols(e);
@@ -4296,12 +4398,12 @@ function ownKeys(e, r) {
4296
4398
  }
4297
4399
  return t;
4298
4400
  }
4299
- function _objectSpread2(e) {
4401
+ function _objectSpread22(e) {
4300
4402
  for (var r = 1; r < arguments.length; r++) {
4301
4403
  var t = null != arguments[r] ? arguments[r] : {};
4302
- r % 2 ? ownKeys(Object(t), true).forEach(function(r$1) {
4303
- _defineProperty(e, r$1, t[r$1]);
4304
- }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r$1) {
4404
+ r % 2 ? ownKeys2(Object(t), true).forEach(function(r$1) {
4405
+ _defineProperty2(e, r$1, t[r$1]);
4406
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys2(Object(t)).forEach(function(r$1) {
4305
4407
  Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t, r$1));
4306
4408
  });
4307
4409
  }
@@ -4338,13 +4440,13 @@ var _getRequestParams = (method, options, parameters, body) => {
4338
4440
  method,
4339
4441
  headers: (options === null || options === void 0 ? void 0 : options.headers) || {}
4340
4442
  };
4341
- if (method === "GET" || method === "HEAD" || !body) return _objectSpread2(_objectSpread2({}, params), parameters);
4443
+ if (method === "GET" || method === "HEAD" || !body) return _objectSpread22(_objectSpread22({}, params), parameters);
4342
4444
  if (isPlainObject(body)) {
4343
- params.headers = _objectSpread2({ "Content-Type": "application/json" }, options === null || options === void 0 ? void 0 : options.headers);
4445
+ params.headers = _objectSpread22({ "Content-Type": "application/json" }, options === null || options === void 0 ? void 0 : options.headers);
4344
4446
  params.body = JSON.stringify(body);
4345
4447
  } else params.body = body;
4346
4448
  if (options === null || options === void 0 ? void 0 : options.duplex) params.duplex = options.duplex;
4347
- return _objectSpread2(_objectSpread2({}, params), parameters);
4449
+ return _objectSpread22(_objectSpread22({}, params), parameters);
4348
4450
  };
4349
4451
  async function _handleRequest(fetcher, method, url, options, parameters, body, namespace) {
4350
4452
  return new Promise((resolve, reject) => {
@@ -4353,6 +4455,7 @@ async function _handleRequest(fetcher, method, url, options, parameters, body, n
4353
4455
  if (options === null || options === void 0 ? void 0 : options.noResolveJson) return result;
4354
4456
  if (namespace === "vectors") {
4355
4457
  const contentType = result.headers.get("content-type");
4458
+ if (result.headers.get("content-length") === "0" || result.status === 204) return {};
4356
4459
  if (!contentType || !contentType.includes("application/json")) return {};
4357
4460
  }
4358
4461
  return result.json();
@@ -4371,7 +4474,7 @@ function createFetchApi(namespace = "storage") {
4371
4474
  return _handleRequest(fetcher, "PUT", url, options, parameters, body, namespace);
4372
4475
  },
4373
4476
  head: async (fetcher, url, options, parameters) => {
4374
- return _handleRequest(fetcher, "HEAD", url, _objectSpread2(_objectSpread2({}, options), {}, { noResolveJson: true }), parameters, void 0, namespace);
4477
+ return _handleRequest(fetcher, "HEAD", url, _objectSpread22(_objectSpread22({}, options), {}, { noResolveJson: true }), parameters, void 0, namespace);
4375
4478
  },
4376
4479
  remove: async (fetcher, url, body, options, parameters) => {
4377
4480
  return _handleRequest(fetcher, "DELETE", url, options, parameters, body, namespace);
@@ -4380,6 +4483,7 @@ function createFetchApi(namespace = "storage") {
4380
4483
  }
4381
4484
  var defaultApi = createFetchApi("storage");
4382
4485
  var { get, post, put, head, remove } = defaultApi;
4486
+ var vectorsApi = createFetchApi("vectors");
4383
4487
  var BaseApiClient = class {
4384
4488
  /**
4385
4489
  * Creates a new BaseApiClient instance
@@ -4543,8 +4647,8 @@ var StorageFileApi = class extends BaseApiClient {
4543
4647
  var _this = this;
4544
4648
  return _this.handleOperation(async () => {
4545
4649
  let body;
4546
- const options = _objectSpread2(_objectSpread2({}, DEFAULT_FILE_OPTIONS), fileOptions);
4547
- let headers = _objectSpread2(_objectSpread2({}, _this.headers), method === "POST" && { "x-upsert": String(options.upsert) });
4650
+ const options = _objectSpread22(_objectSpread22({}, DEFAULT_FILE_OPTIONS), fileOptions);
4651
+ let headers = _objectSpread22(_objectSpread22({}, _this.headers), method === "POST" && { "x-upsert": String(options.upsert) });
4548
4652
  const metadata = options.metadata;
4549
4653
  if (typeof Blob !== "undefined" && fileBody instanceof Blob) {
4550
4654
  body = new FormData();
@@ -4562,10 +4666,10 @@ var StorageFileApi = class extends BaseApiClient {
4562
4666
  if (metadata) headers["x-metadata"] = _this.toBase64(_this.encodeMetadata(metadata));
4563
4667
  if ((typeof ReadableStream !== "undefined" && body instanceof ReadableStream || body && typeof body === "object" && "pipe" in body && typeof body.pipe === "function") && !options.duplex) options.duplex = "half";
4564
4668
  }
4565
- if (fileOptions === null || fileOptions === void 0 ? void 0 : fileOptions.headers) headers = _objectSpread2(_objectSpread2({}, headers), fileOptions.headers);
4669
+ if (fileOptions === null || fileOptions === void 0 ? void 0 : fileOptions.headers) headers = _objectSpread22(_objectSpread22({}, headers), fileOptions.headers);
4566
4670
  const cleanPath = _this._removeEmptyFolders(path);
4567
4671
  const _path = _this._getFinalPath(cleanPath);
4568
- const data = await (method == "PUT" ? put : post)(_this.fetch, `${_this.url}/object/${_path}`, body, _objectSpread2({ headers }, (options === null || options === void 0 ? void 0 : options.duplex) ? { duplex: options.duplex } : {}));
4672
+ const data = await (method == "PUT" ? put : post)(_this.fetch, `${_this.url}/object/${_path}`, body, _objectSpread22({ headers }, (options === null || options === void 0 ? void 0 : options.duplex) ? { duplex: options.duplex } : {}));
4569
4673
  return {
4570
4674
  path: cleanPath,
4571
4675
  id: data.Id,
@@ -4659,8 +4763,8 @@ var StorageFileApi = class extends BaseApiClient {
4659
4763
  url.searchParams.set("token", token);
4660
4764
  return _this3.handleOperation(async () => {
4661
4765
  let body;
4662
- const options = _objectSpread2({ upsert: DEFAULT_FILE_OPTIONS.upsert }, fileOptions);
4663
- const headers = _objectSpread2(_objectSpread2({}, _this3.headers), { "x-upsert": String(options.upsert) });
4766
+ const options = _objectSpread22({ upsert: DEFAULT_FILE_OPTIONS.upsert }, fileOptions);
4767
+ const headers = _objectSpread22(_objectSpread22({}, _this3.headers), { "x-upsert": String(options.upsert) });
4664
4768
  if (typeof Blob !== "undefined" && fileBody instanceof Blob) {
4665
4769
  body = new FormData();
4666
4770
  body.append("cacheControl", options.cacheControl);
@@ -4713,7 +4817,7 @@ var StorageFileApi = class extends BaseApiClient {
4713
4817
  var _this4 = this;
4714
4818
  return _this4.handleOperation(async () => {
4715
4819
  let _path = _this4._getFinalPath(path);
4716
- const headers = _objectSpread2({}, _this4.headers);
4820
+ const headers = _objectSpread22({}, _this4.headers);
4717
4821
  if (options === null || options === void 0 ? void 0 : options.upsert) headers["x-upsert"] = "true";
4718
4822
  const data = await post(_this4.fetch, `${_this4.url}/object/upload/sign/${_path}`, {}, { headers });
4719
4823
  const url = new URL(_this4.url + data.url);
@@ -4904,7 +5008,7 @@ var StorageFileApi = class extends BaseApiClient {
4904
5008
  var _this8 = this;
4905
5009
  return _this8.handleOperation(async () => {
4906
5010
  let _path = _this8._getFinalPath(path);
4907
- let data = await post(_this8.fetch, `${_this8.url}/object/sign/${_path}`, _objectSpread2({ expiresIn }, (options === null || options === void 0 ? void 0 : options.transform) ? { transform: options.transform } : {}), { headers: _this8.headers });
5011
+ let data = await post(_this8.fetch, `${_this8.url}/object/sign/${_path}`, _objectSpread22({ expiresIn }, (options === null || options === void 0 ? void 0 : options.transform) ? { transform: options.transform } : {}), { headers: _this8.headers });
4908
5012
  const downloadQueryParam = (options === null || options === void 0 ? void 0 : options.download) ? `&download=${options.download === true ? "" : options.download}` : "";
4909
5013
  return { signedUrl: encodeURI(`${_this8.url}${data.signedURL}${downloadQueryParam}`) };
4910
5014
  });
@@ -4955,7 +5059,7 @@ var StorageFileApi = class extends BaseApiClient {
4955
5059
  paths
4956
5060
  }, { headers: _this9.headers });
4957
5061
  const downloadQueryParam = (options === null || options === void 0 ? void 0 : options.download) ? `&download=${options.download === true ? "" : options.download}` : "";
4958
- return data.map((datum) => _objectSpread2(_objectSpread2({}, datum), {}, { signedUrl: datum.signedURL ? encodeURI(`${_this9.url}${datum.signedURL}${downloadQueryParam}`) : null }));
5062
+ return data.map((datum) => _objectSpread22(_objectSpread22({}, datum), {}, { signedUrl: datum.signedURL ? encodeURI(`${_this9.url}${datum.signedURL}${downloadQueryParam}`) : null }));
4959
5063
  });
4960
5064
  }
4961
5065
  /**
@@ -4964,6 +5068,7 @@ var StorageFileApi = class extends BaseApiClient {
4964
5068
  * @category File Buckets
4965
5069
  * @param path The full path and file name of the file to be downloaded. For example `folder/image.png`.
4966
5070
  * @param options.transform Transform the asset before serving it to the client.
5071
+ * @param parameters Additional fetch parameters like signal for cancellation. Supports standard fetch options including cache control.
4967
5072
  * @returns BlobDownloadBuilder instance for downloading the file
4968
5073
  *
4969
5074
  * @example Download file
@@ -4995,8 +5100,27 @@ var StorageFileApi = class extends BaseApiClient {
4995
5100
  * }
4996
5101
  * })
4997
5102
  * ```
5103
+ *
5104
+ * @example Download with cache control (useful in Edge Functions)
5105
+ * ```js
5106
+ * const { data, error } = await supabase
5107
+ * .storage
5108
+ * .from('avatars')
5109
+ * .download('folder/avatar1.png', {}, { cache: 'no-store' })
5110
+ * ```
5111
+ *
5112
+ * @example Download with abort signal
5113
+ * ```js
5114
+ * const controller = new AbortController()
5115
+ * setTimeout(() => controller.abort(), 5000)
5116
+ *
5117
+ * const { data, error } = await supabase
5118
+ * .storage
5119
+ * .from('avatars')
5120
+ * .download('folder/avatar1.png', {}, { signal: controller.signal })
5121
+ * ```
4998
5122
  */
4999
- download(path, options) {
5123
+ download(path, options, parameters) {
5000
5124
  const renderPath = typeof (options === null || options === void 0 ? void 0 : options.transform) !== "undefined" ? "render/image/authenticated" : "object";
5001
5125
  const transformationQuery = this.transformOptsToQueryString((options === null || options === void 0 ? void 0 : options.transform) || {});
5002
5126
  const queryString = transformationQuery ? `?${transformationQuery}` : "";
@@ -5004,7 +5128,7 @@ var StorageFileApi = class extends BaseApiClient {
5004
5128
  const downloadFn = () => get(this.fetch, `${this.url}/${renderPath}/${_path}${queryString}`, {
5005
5129
  headers: this.headers,
5006
5130
  noResolveJson: true
5007
- });
5131
+ }, parameters);
5008
5132
  return new BlobDownloadBuilder(downloadFn, this.shouldThrowOnError);
5009
5133
  }
5010
5134
  /**
@@ -5227,7 +5351,7 @@ var StorageFileApi = class extends BaseApiClient {
5227
5351
  async list(path, options, parameters) {
5228
5352
  var _this13 = this;
5229
5353
  return _this13.handleOperation(async () => {
5230
- const body = _objectSpread2(_objectSpread2(_objectSpread2({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path || "" });
5354
+ const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path || "" });
5231
5355
  return await post(_this13.fetch, `${_this13.url}/object/list/${_this13.bucketId}`, body, { headers: _this13.headers }, parameters);
5232
5356
  });
5233
5357
  }
@@ -5241,7 +5365,7 @@ var StorageFileApi = class extends BaseApiClient {
5241
5365
  async listV2(options, parameters) {
5242
5366
  var _this14 = this;
5243
5367
  return _this14.handleOperation(async () => {
5244
- const body = _objectSpread2({}, options);
5368
+ const body = _objectSpread22({}, options);
5245
5369
  return await post(_this14.fetch, `${_this14.url}/object/list-v2/${_this14.bucketId}`, body, { headers: _this14.headers }, parameters);
5246
5370
  });
5247
5371
  }
@@ -5268,7 +5392,7 @@ var StorageFileApi = class extends BaseApiClient {
5268
5392
  return params.join("&");
5269
5393
  }
5270
5394
  };
5271
- var version2 = "2.93.2";
5395
+ var version2 = "2.95.3";
5272
5396
  var DEFAULT_HEADERS = { "X-Client-Info": `storage-js/${version2}` };
5273
5397
  var StorageBucketApi = class extends BaseApiClient {
5274
5398
  constructor(url, headers = {}, fetch$1, opts) {
@@ -5277,7 +5401,7 @@ var StorageBucketApi = class extends BaseApiClient {
5277
5401
  if (/supabase\.(co|in|red)$/.test(baseUrl.hostname) && !baseUrl.hostname.includes("storage.supabase.")) baseUrl.hostname = baseUrl.hostname.replace("supabase.", "storage.supabase.");
5278
5402
  }
5279
5403
  const finalUrl = baseUrl.href.replace(/\/$/, "");
5280
- const finalHeaders = _objectSpread2(_objectSpread2({}, DEFAULT_HEADERS), headers);
5404
+ const finalHeaders = _objectSpread22(_objectSpread22({}, DEFAULT_HEADERS), headers);
5281
5405
  super(finalUrl, finalHeaders, fetch$1, "storage");
5282
5406
  }
5283
5407
  /**
@@ -5548,7 +5672,7 @@ var StorageAnalyticsClient = class extends BaseApiClient {
5548
5672
  */
5549
5673
  constructor(url, headers = {}, fetch$1) {
5550
5674
  const finalUrl = url.replace(/\/$/, "");
5551
- const finalHeaders = _objectSpread2(_objectSpread2({}, DEFAULT_HEADERS), headers);
5675
+ const finalHeaders = _objectSpread22(_objectSpread22({}, DEFAULT_HEADERS), headers);
5552
5676
  super(finalUrl, finalHeaders, fetch$1, "storage");
5553
5677
  }
5554
5678
  /**
@@ -5848,21 +5972,21 @@ var VectorIndexApi = class extends BaseApiClient {
5848
5972
  /** Creates a new VectorIndexApi instance */
5849
5973
  constructor(url, headers = {}, fetch$1) {
5850
5974
  const finalUrl = url.replace(/\/$/, "");
5851
- const finalHeaders = _objectSpread2(_objectSpread2({}, DEFAULT_HEADERS), {}, { "Content-Type": "application/json" }, headers);
5975
+ const finalHeaders = _objectSpread22(_objectSpread22({}, DEFAULT_HEADERS), {}, { "Content-Type": "application/json" }, headers);
5852
5976
  super(finalUrl, finalHeaders, fetch$1, "vectors");
5853
5977
  }
5854
5978
  /** Creates a new vector index within a bucket */
5855
5979
  async createIndex(options) {
5856
5980
  var _this = this;
5857
5981
  return _this.handleOperation(async () => {
5858
- return await post(_this.fetch, `${_this.url}/CreateIndex`, options, { headers: _this.headers }) || {};
5982
+ return await vectorsApi.post(_this.fetch, `${_this.url}/CreateIndex`, options, { headers: _this.headers }) || {};
5859
5983
  });
5860
5984
  }
5861
5985
  /** Retrieves metadata for a specific vector index */
5862
5986
  async getIndex(vectorBucketName, indexName) {
5863
5987
  var _this2 = this;
5864
5988
  return _this2.handleOperation(async () => {
5865
- return await post(_this2.fetch, `${_this2.url}/GetIndex`, {
5989
+ return await vectorsApi.post(_this2.fetch, `${_this2.url}/GetIndex`, {
5866
5990
  vectorBucketName,
5867
5991
  indexName
5868
5992
  }, { headers: _this2.headers });
@@ -5872,14 +5996,14 @@ var VectorIndexApi = class extends BaseApiClient {
5872
5996
  async listIndexes(options) {
5873
5997
  var _this3 = this;
5874
5998
  return _this3.handleOperation(async () => {
5875
- return await post(_this3.fetch, `${_this3.url}/ListIndexes`, options, { headers: _this3.headers });
5999
+ return await vectorsApi.post(_this3.fetch, `${_this3.url}/ListIndexes`, options, { headers: _this3.headers });
5876
6000
  });
5877
6001
  }
5878
6002
  /** Deletes a vector index and all its data */
5879
6003
  async deleteIndex(vectorBucketName, indexName) {
5880
6004
  var _this4 = this;
5881
6005
  return _this4.handleOperation(async () => {
5882
- return await post(_this4.fetch, `${_this4.url}/DeleteIndex`, {
6006
+ return await vectorsApi.post(_this4.fetch, `${_this4.url}/DeleteIndex`, {
5883
6007
  vectorBucketName,
5884
6008
  indexName
5885
6009
  }, { headers: _this4.headers }) || {};
@@ -5890,7 +6014,7 @@ var VectorDataApi = class extends BaseApiClient {
5890
6014
  /** Creates a new VectorDataApi instance */
5891
6015
  constructor(url, headers = {}, fetch$1) {
5892
6016
  const finalUrl = url.replace(/\/$/, "");
5893
- const finalHeaders = _objectSpread2(_objectSpread2({}, DEFAULT_HEADERS), {}, { "Content-Type": "application/json" }, headers);
6017
+ const finalHeaders = _objectSpread22(_objectSpread22({}, DEFAULT_HEADERS), {}, { "Content-Type": "application/json" }, headers);
5894
6018
  super(finalUrl, finalHeaders, fetch$1, "vectors");
5895
6019
  }
5896
6020
  /** Inserts or updates vectors in batch (1-500 per request) */
@@ -5898,14 +6022,14 @@ var VectorDataApi = class extends BaseApiClient {
5898
6022
  var _this = this;
5899
6023
  if (options.vectors.length < 1 || options.vectors.length > 500) throw new Error("Vector batch size must be between 1 and 500 items");
5900
6024
  return _this.handleOperation(async () => {
5901
- return await post(_this.fetch, `${_this.url}/PutVectors`, options, { headers: _this.headers }) || {};
6025
+ return await vectorsApi.post(_this.fetch, `${_this.url}/PutVectors`, options, { headers: _this.headers }) || {};
5902
6026
  });
5903
6027
  }
5904
6028
  /** Retrieves vectors by their keys in batch */
5905
6029
  async getVectors(options) {
5906
6030
  var _this2 = this;
5907
6031
  return _this2.handleOperation(async () => {
5908
- return await post(_this2.fetch, `${_this2.url}/GetVectors`, options, { headers: _this2.headers });
6032
+ return await vectorsApi.post(_this2.fetch, `${_this2.url}/GetVectors`, options, { headers: _this2.headers });
5909
6033
  });
5910
6034
  }
5911
6035
  /** Lists vectors in an index with pagination */
@@ -5918,14 +6042,14 @@ var VectorDataApi = class extends BaseApiClient {
5918
6042
  }
5919
6043
  }
5920
6044
  return _this3.handleOperation(async () => {
5921
- return await post(_this3.fetch, `${_this3.url}/ListVectors`, options, { headers: _this3.headers });
6045
+ return await vectorsApi.post(_this3.fetch, `${_this3.url}/ListVectors`, options, { headers: _this3.headers });
5922
6046
  });
5923
6047
  }
5924
6048
  /** Queries for similar vectors using approximate nearest neighbor search */
5925
6049
  async queryVectors(options) {
5926
6050
  var _this4 = this;
5927
6051
  return _this4.handleOperation(async () => {
5928
- return await post(_this4.fetch, `${_this4.url}/QueryVectors`, options, { headers: _this4.headers });
6052
+ return await vectorsApi.post(_this4.fetch, `${_this4.url}/QueryVectors`, options, { headers: _this4.headers });
5929
6053
  });
5930
6054
  }
5931
6055
  /** Deletes vectors by their keys in batch (1-500 per request) */
@@ -5933,7 +6057,7 @@ var VectorDataApi = class extends BaseApiClient {
5933
6057
  var _this5 = this;
5934
6058
  if (options.keys.length < 1 || options.keys.length > 500) throw new Error("Keys batch size must be between 1 and 500 items");
5935
6059
  return _this5.handleOperation(async () => {
5936
- return await post(_this5.fetch, `${_this5.url}/DeleteVectors`, options, { headers: _this5.headers }) || {};
6060
+ return await vectorsApi.post(_this5.fetch, `${_this5.url}/DeleteVectors`, options, { headers: _this5.headers }) || {};
5937
6061
  });
5938
6062
  }
5939
6063
  };
@@ -5941,35 +6065,35 @@ var VectorBucketApi = class extends BaseApiClient {
5941
6065
  /** Creates a new VectorBucketApi instance */
5942
6066
  constructor(url, headers = {}, fetch$1) {
5943
6067
  const finalUrl = url.replace(/\/$/, "");
5944
- const finalHeaders = _objectSpread2(_objectSpread2({}, DEFAULT_HEADERS), {}, { "Content-Type": "application/json" }, headers);
6068
+ const finalHeaders = _objectSpread22(_objectSpread22({}, DEFAULT_HEADERS), {}, { "Content-Type": "application/json" }, headers);
5945
6069
  super(finalUrl, finalHeaders, fetch$1, "vectors");
5946
6070
  }
5947
6071
  /** Creates a new vector bucket */
5948
6072
  async createBucket(vectorBucketName) {
5949
6073
  var _this = this;
5950
6074
  return _this.handleOperation(async () => {
5951
- return await post(_this.fetch, `${_this.url}/CreateVectorBucket`, { vectorBucketName }, { headers: _this.headers }) || {};
6075
+ return await vectorsApi.post(_this.fetch, `${_this.url}/CreateVectorBucket`, { vectorBucketName }, { headers: _this.headers }) || {};
5952
6076
  });
5953
6077
  }
5954
6078
  /** Retrieves metadata for a specific vector bucket */
5955
6079
  async getBucket(vectorBucketName) {
5956
6080
  var _this2 = this;
5957
6081
  return _this2.handleOperation(async () => {
5958
- return await post(_this2.fetch, `${_this2.url}/GetVectorBucket`, { vectorBucketName }, { headers: _this2.headers });
6082
+ return await vectorsApi.post(_this2.fetch, `${_this2.url}/GetVectorBucket`, { vectorBucketName }, { headers: _this2.headers });
5959
6083
  });
5960
6084
  }
5961
6085
  /** Lists vector buckets with optional filtering and pagination */
5962
6086
  async listBuckets(options = {}) {
5963
6087
  var _this3 = this;
5964
6088
  return _this3.handleOperation(async () => {
5965
- return await post(_this3.fetch, `${_this3.url}/ListVectorBuckets`, options, { headers: _this3.headers });
6089
+ return await vectorsApi.post(_this3.fetch, `${_this3.url}/ListVectorBuckets`, options, { headers: _this3.headers });
5966
6090
  });
5967
6091
  }
5968
6092
  /** Deletes a vector bucket (must be empty first) */
5969
6093
  async deleteBucket(vectorBucketName) {
5970
6094
  var _this4 = this;
5971
6095
  return _this4.handleOperation(async () => {
5972
- return await post(_this4.fetch, `${_this4.url}/DeleteVectorBucket`, { vectorBucketName }, { headers: _this4.headers }) || {};
6096
+ return await vectorsApi.post(_this4.fetch, `${_this4.url}/DeleteVectorBucket`, { vectorBucketName }, { headers: _this4.headers }) || {};
5973
6097
  });
5974
6098
  }
5975
6099
  };
@@ -6167,7 +6291,7 @@ var VectorBucketScope = class extends VectorIndexApi {
6167
6291
  */
6168
6292
  async createIndex(options) {
6169
6293
  var _superprop_getCreateIndex = () => super.createIndex, _this5 = this;
6170
- return _superprop_getCreateIndex().call(_this5, _objectSpread2(_objectSpread2({}, options), {}, { vectorBucketName: _this5.vectorBucketName }));
6294
+ return _superprop_getCreateIndex().call(_this5, _objectSpread22(_objectSpread22({}, options), {}, { vectorBucketName: _this5.vectorBucketName }));
6171
6295
  }
6172
6296
  /**
6173
6297
  *
@@ -6190,7 +6314,7 @@ var VectorBucketScope = class extends VectorIndexApi {
6190
6314
  */
6191
6315
  async listIndexes(options = {}) {
6192
6316
  var _superprop_getListIndexes = () => super.listIndexes, _this6 = this;
6193
- return _superprop_getListIndexes().call(_this6, _objectSpread2(_objectSpread2({}, options), {}, { vectorBucketName: _this6.vectorBucketName }));
6317
+ return _superprop_getListIndexes().call(_this6, _objectSpread22(_objectSpread22({}, options), {}, { vectorBucketName: _this6.vectorBucketName }));
6194
6318
  }
6195
6319
  /**
6196
6320
  *
@@ -6323,7 +6447,7 @@ var VectorIndexScope = class extends VectorDataApi {
6323
6447
  */
6324
6448
  async putVectors(options) {
6325
6449
  var _superprop_getPutVectors = () => super.putVectors, _this9 = this;
6326
- return _superprop_getPutVectors().call(_this9, _objectSpread2(_objectSpread2({}, options), {}, {
6450
+ return _superprop_getPutVectors().call(_this9, _objectSpread22(_objectSpread22({}, options), {}, {
6327
6451
  vectorBucketName: _this9.vectorBucketName,
6328
6452
  indexName: _this9.indexName
6329
6453
  }));
@@ -6352,7 +6476,7 @@ var VectorIndexScope = class extends VectorDataApi {
6352
6476
  */
6353
6477
  async getVectors(options) {
6354
6478
  var _superprop_getGetVectors = () => super.getVectors, _this10 = this;
6355
- return _superprop_getGetVectors().call(_this10, _objectSpread2(_objectSpread2({}, options), {}, {
6479
+ return _superprop_getGetVectors().call(_this10, _objectSpread22(_objectSpread22({}, options), {}, {
6356
6480
  vectorBucketName: _this10.vectorBucketName,
6357
6481
  indexName: _this10.indexName
6358
6482
  }));
@@ -6381,7 +6505,7 @@ var VectorIndexScope = class extends VectorDataApi {
6381
6505
  */
6382
6506
  async listVectors(options = {}) {
6383
6507
  var _superprop_getListVectors = () => super.listVectors, _this11 = this;
6384
- return _superprop_getListVectors().call(_this11, _objectSpread2(_objectSpread2({}, options), {}, {
6508
+ return _superprop_getListVectors().call(_this11, _objectSpread22(_objectSpread22({}, options), {}, {
6385
6509
  vectorBucketName: _this11.vectorBucketName,
6386
6510
  indexName: _this11.indexName
6387
6511
  }));
@@ -6413,7 +6537,7 @@ var VectorIndexScope = class extends VectorDataApi {
6413
6537
  */
6414
6538
  async queryVectors(options) {
6415
6539
  var _superprop_getQueryVectors = () => super.queryVectors, _this12 = this;
6416
- return _superprop_getQueryVectors().call(_this12, _objectSpread2(_objectSpread2({}, options), {}, {
6540
+ return _superprop_getQueryVectors().call(_this12, _objectSpread22(_objectSpread22({}, options), {}, {
6417
6541
  vectorBucketName: _this12.vectorBucketName,
6418
6542
  indexName: _this12.indexName
6419
6543
  }));
@@ -6441,7 +6565,7 @@ var VectorIndexScope = class extends VectorDataApi {
6441
6565
  */
6442
6566
  async deleteVectors(options) {
6443
6567
  var _superprop_getDeleteVectors = () => super.deleteVectors, _this13 = this;
6444
- return _superprop_getDeleteVectors().call(_this13, _objectSpread2(_objectSpread2({}, options), {}, {
6568
+ return _superprop_getDeleteVectors().call(_this13, _objectSpread22(_objectSpread22({}, options), {}, {
6445
6569
  vectorBucketName: _this13.vectorBucketName,
6446
6570
  indexName: _this13.indexName
6447
6571
  }));
@@ -6513,7 +6637,7 @@ var StorageClient = class extends StorageBucketApi {
6513
6637
  };
6514
6638
 
6515
6639
  // ../../node_modules/@supabase/auth-js/dist/module/lib/version.js
6516
- var version3 = "2.93.2";
6640
+ var version3 = "2.95.3";
6517
6641
 
6518
6642
  // ../../node_modules/@supabase/auth-js/dist/module/lib/constants.js
6519
6643
  var AUTO_REFRESH_TICK_DURATION_MS = 30 * 1e3;
@@ -8281,6 +8405,7 @@ var WebAuthnApi = class {
8281
8405
  * @see {@link https://w3c.github.io/webauthn/#sctn-verifying-assertion W3C WebAuthn Spec - Verifying Assertion}
8282
8406
  */
8283
8407
  async _challenge({ factorId, webauthn, friendlyName, signal }, overrides) {
8408
+ var _a;
8284
8409
  try {
8285
8410
  const { data: challengeResponse, error: challengeError } = await this.client.mfa.challenge({
8286
8411
  factorId,
@@ -8293,7 +8418,15 @@ var WebAuthnApi = class {
8293
8418
  if (challengeResponse.webauthn.type === "create") {
8294
8419
  const { user } = challengeResponse.webauthn.credential_options.publicKey;
8295
8420
  if (!user.name) {
8296
- user.name = `${user.id}:${friendlyName}`;
8421
+ const nameToUse = friendlyName;
8422
+ if (!nameToUse) {
8423
+ const currentUser = await this.client.getUser();
8424
+ const userData = currentUser.data.user;
8425
+ const fallbackName = ((_a = userData === null || userData === void 0 ? void 0 : userData.user_metadata) === null || _a === void 0 ? void 0 : _a.name) || (userData === null || userData === void 0 ? void 0 : userData.email) || (userData === null || userData === void 0 ? void 0 : userData.id) || "User";
8426
+ user.name = `${user.id}:${fallbackName}`;
8427
+ } else {
8428
+ user.name = `${user.id}:${nameToUse}`;
8429
+ }
8297
8430
  }
8298
8431
  if (!user.displayName) {
8299
8432
  user.displayName = user.name;
@@ -10803,7 +10936,7 @@ var GoTrueClient = class _GoTrueClient {
10803
10936
  * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
10804
10937
  *
10805
10938
  * Returns authorization details including client info, scopes, and user information.
10806
- * If the API returns a redirect_uri, it means consent was already given - the caller
10939
+ * If the response includes only a redirect_url field, it means consent was already given - the caller
10807
10940
  * should handle the redirect manually if needed.
10808
10941
  */
10809
10942
  async _getAuthorizationDetails(authorizationId) {
@@ -11057,7 +11190,7 @@ var AuthClient = GoTrueClient_default;
11057
11190
  var AuthClient_default = AuthClient;
11058
11191
 
11059
11192
  // ../../node_modules/@supabase/supabase-js/dist/index.mjs
11060
- var version4 = "2.93.2";
11193
+ var version4 = "2.95.3";
11061
11194
  var JS_ENV = "";
11062
11195
  if (typeof Deno !== "undefined") JS_ENV = "deno";
11063
11196
  else if (typeof document !== "undefined") JS_ENV = "web";
@@ -11073,37 +11206,37 @@ var DEFAULT_AUTH_OPTIONS = {
11073
11206
  flowType: "implicit"
11074
11207
  };
11075
11208
  var DEFAULT_REALTIME_OPTIONS = {};
11076
- function _typeof2(o) {
11209
+ function _typeof3(o) {
11077
11210
  "@babel/helpers - typeof";
11078
- return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
11211
+ return _typeof3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
11079
11212
  return typeof o$1;
11080
11213
  } : function(o$1) {
11081
11214
  return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
11082
- }, _typeof2(o);
11215
+ }, _typeof3(o);
11083
11216
  }
11084
- function toPrimitive2(t, r) {
11085
- if ("object" != _typeof2(t) || !t) return t;
11217
+ function toPrimitive3(t, r) {
11218
+ if ("object" != _typeof3(t) || !t) return t;
11086
11219
  var e = t[Symbol.toPrimitive];
11087
11220
  if (void 0 !== e) {
11088
11221
  var i = e.call(t, r || "default");
11089
- if ("object" != _typeof2(i)) return i;
11222
+ if ("object" != _typeof3(i)) return i;
11090
11223
  throw new TypeError("@@toPrimitive must return a primitive value.");
11091
11224
  }
11092
11225
  return ("string" === r ? String : Number)(t);
11093
11226
  }
11094
- function toPropertyKey2(t) {
11095
- var i = toPrimitive2(t, "string");
11096
- return "symbol" == _typeof2(i) ? i : i + "";
11227
+ function toPropertyKey3(t) {
11228
+ var i = toPrimitive3(t, "string");
11229
+ return "symbol" == _typeof3(i) ? i : i + "";
11097
11230
  }
11098
- function _defineProperty2(e, r, t) {
11099
- return (r = toPropertyKey2(r)) in e ? Object.defineProperty(e, r, {
11231
+ function _defineProperty3(e, r, t) {
11232
+ return (r = toPropertyKey3(r)) in e ? Object.defineProperty(e, r, {
11100
11233
  value: t,
11101
11234
  enumerable: true,
11102
11235
  configurable: true,
11103
11236
  writable: true
11104
11237
  }) : e[r] = t, e;
11105
11238
  }
11106
- function ownKeys2(e, r) {
11239
+ function ownKeys3(e, r) {
11107
11240
  var t = Object.keys(e);
11108
11241
  if (Object.getOwnPropertySymbols) {
11109
11242
  var o = Object.getOwnPropertySymbols(e);
@@ -11113,12 +11246,12 @@ function ownKeys2(e, r) {
11113
11246
  }
11114
11247
  return t;
11115
11248
  }
11116
- function _objectSpread22(e) {
11249
+ function _objectSpread23(e) {
11117
11250
  for (var r = 1; r < arguments.length; r++) {
11118
11251
  var t = null != arguments[r] ? arguments[r] : {};
11119
- r % 2 ? ownKeys2(Object(t), true).forEach(function(r$1) {
11120
- _defineProperty2(e, r$1, t[r$1]);
11121
- }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys2(Object(t)).forEach(function(r$1) {
11252
+ r % 2 ? ownKeys3(Object(t), true).forEach(function(r$1) {
11253
+ _defineProperty3(e, r$1, t[r$1]);
11254
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys3(Object(t)).forEach(function(r$1) {
11122
11255
  Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t, r$1));
11123
11256
  });
11124
11257
  }
@@ -11140,7 +11273,7 @@ var fetchWithAuth = (supabaseKey, getAccessToken, customFetch) => {
11140
11273
  let headers = new HeadersConstructor(init === null || init === void 0 ? void 0 : init.headers);
11141
11274
  if (!headers.has("apikey")) headers.set("apikey", supabaseKey);
11142
11275
  if (!headers.has("Authorization")) headers.set("Authorization", `Bearer ${accessToken}`);
11143
- return fetch$1(input, _objectSpread22(_objectSpread22({}, init), {}, { headers }));
11276
+ return fetch$1(input, _objectSpread23(_objectSpread23({}, init), {}, { headers }));
11144
11277
  };
11145
11278
  };
11146
11279
  function ensureTrailingSlash(url) {
@@ -11151,11 +11284,11 @@ function applySettingDefaults(options, defaults) {
11151
11284
  const { db: dbOptions, auth: authOptions, realtime: realtimeOptions, global: globalOptions } = options;
11152
11285
  const { db: DEFAULT_DB_OPTIONS$1, auth: DEFAULT_AUTH_OPTIONS$1, realtime: DEFAULT_REALTIME_OPTIONS$1, global: DEFAULT_GLOBAL_OPTIONS$1 } = defaults;
11153
11286
  const result = {
11154
- db: _objectSpread22(_objectSpread22({}, DEFAULT_DB_OPTIONS$1), dbOptions),
11155
- auth: _objectSpread22(_objectSpread22({}, DEFAULT_AUTH_OPTIONS$1), authOptions),
11156
- realtime: _objectSpread22(_objectSpread22({}, DEFAULT_REALTIME_OPTIONS$1), realtimeOptions),
11287
+ db: _objectSpread23(_objectSpread23({}, DEFAULT_DB_OPTIONS$1), dbOptions),
11288
+ auth: _objectSpread23(_objectSpread23({}, DEFAULT_AUTH_OPTIONS$1), authOptions),
11289
+ realtime: _objectSpread23(_objectSpread23({}, DEFAULT_REALTIME_OPTIONS$1), realtimeOptions),
11157
11290
  storage: {},
11158
- global: _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_GLOBAL_OPTIONS$1), globalOptions), {}, { headers: _objectSpread22(_objectSpread22({}, (_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 : {}) }),
11291
+ global: _objectSpread23(_objectSpread23(_objectSpread23({}, DEFAULT_GLOBAL_OPTIONS$1), globalOptions), {}, { headers: _objectSpread23(_objectSpread23({}, (_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 : {}) }),
11159
11292
  accessToken: async () => ""
11160
11293
  };
11161
11294
  if (options.accessToken) result.accessToken = options.accessToken;
@@ -11213,7 +11346,7 @@ var SupabaseClient = class {
11213
11346
  const DEFAULTS = {
11214
11347
  db: DEFAULT_DB_OPTIONS,
11215
11348
  realtime: DEFAULT_REALTIME_OPTIONS,
11216
- auth: _objectSpread22(_objectSpread22({}, DEFAULT_AUTH_OPTIONS), {}, { storageKey: defaultStorageKey }),
11349
+ auth: _objectSpread23(_objectSpread23({}, DEFAULT_AUTH_OPTIONS), {}, { storageKey: defaultStorageKey }),
11217
11350
  global: DEFAULT_GLOBAL_OPTIONS
11218
11351
  };
11219
11352
  const settings = applySettingDefaults(options !== null && options !== void 0 ? options : {}, DEFAULTS);
@@ -11229,7 +11362,7 @@ var SupabaseClient = class {
11229
11362
  } });
11230
11363
  }
11231
11364
  this.fetch = fetchWithAuth(supabaseKey, this._getAccessToken.bind(this), settings.global.fetch);
11232
- this.realtime = this._initRealtimeClient(_objectSpread22({
11365
+ this.realtime = this._initRealtimeClient(_objectSpread23({
11233
11366
  headers: this.headers,
11234
11367
  accessToken: this._getAccessToken.bind(this)
11235
11368
  }, settings.realtime));
@@ -11237,7 +11370,9 @@ var SupabaseClient = class {
11237
11370
  this.rest = new PostgrestClient(new URL("rest/v1", baseUrl).href, {
11238
11371
  headers: this.headers,
11239
11372
  schema: settings.db.schema,
11240
- fetch: this.fetch
11373
+ fetch: this.fetch,
11374
+ timeout: settings.db.timeout,
11375
+ urlLengthLimit: settings.db.urlLengthLimit
11241
11376
  });
11242
11377
  this.storage = new StorageClient(this.storageUrl.href, this.headers, this.fetch, options === null || options === void 0 ? void 0 : options.storage);
11243
11378
  if (!settings.accessToken) this._listenForAuthEvents();
@@ -11344,7 +11479,7 @@ var SupabaseClient = class {
11344
11479
  };
11345
11480
  return new SupabaseAuthClient({
11346
11481
  url: this.authUrl.href,
11347
- headers: _objectSpread22(_objectSpread22({}, authHeaders), headers),
11482
+ headers: _objectSpread23(_objectSpread23({}, authHeaders), headers),
11348
11483
  storageKey,
11349
11484
  autoRefreshToken,
11350
11485
  persistSession,
@@ -11360,7 +11495,7 @@ var SupabaseClient = class {
11360
11495
  });
11361
11496
  }
11362
11497
  _initRealtimeClient(options) {
11363
- return new RealtimeClient(this.realtimeUrl.href, _objectSpread22(_objectSpread22({}, options), {}, { params: _objectSpread22(_objectSpread22({}, { apikey: this.supabaseKey }), options === null || options === void 0 ? void 0 : options.params) }));
11498
+ return new RealtimeClient(this.realtimeUrl.href, _objectSpread23(_objectSpread23({}, options), {}, { params: _objectSpread23(_objectSpread23({}, { apikey: this.supabaseKey }), options === null || options === void 0 ? void 0 : options.params) }));
11364
11499
  }
11365
11500
  _listenForAuthEvents() {
11366
11501
  return this.auth.onAuthStateChange((event, session) => {
@@ -11405,6 +11540,7 @@ var ContextCaptureManager = class {
11405
11540
  this.networkRequests = [];
11406
11541
  this.navigationHistory = [];
11407
11542
  this.originalConsole = {};
11543
+ this.fetchHost = null;
11408
11544
  this.isCapturing = false;
11409
11545
  }
11410
11546
  /**
@@ -11427,8 +11563,9 @@ var ContextCaptureManager = class {
11427
11563
  if (this.originalConsole.warn) console.warn = this.originalConsole.warn;
11428
11564
  if (this.originalConsole.error) console.error = this.originalConsole.error;
11429
11565
  if (this.originalConsole.info) console.info = this.originalConsole.info;
11430
- if (this.originalFetch && typeof window !== "undefined") {
11431
- window.fetch = this.originalFetch;
11566
+ if (this.originalFetch && this.fetchHost) {
11567
+ this.fetchHost.fetch = this.originalFetch;
11568
+ this.fetchHost = null;
11432
11569
  }
11433
11570
  if (typeof window !== "undefined" && typeof history !== "undefined") {
11434
11571
  if (this.originalPushState) {
@@ -11467,7 +11604,7 @@ var ContextCaptureManager = class {
11467
11604
  if (this.navigationHistory.length > 0) {
11468
11605
  return this.navigationHistory[this.navigationHistory.length - 1];
11469
11606
  }
11470
- if (typeof window !== "undefined") {
11607
+ if (typeof window !== "undefined" && window.location) {
11471
11608
  return window.location.pathname;
11472
11609
  }
11473
11610
  return "unknown";
@@ -11537,15 +11674,19 @@ var ContextCaptureManager = class {
11537
11674
  });
11538
11675
  }
11539
11676
  captureFetch() {
11540
- if (typeof window === "undefined" || typeof fetch === "undefined" || typeof document === "undefined") return;
11541
- this.originalFetch = window.fetch;
11677
+ if (typeof fetch === "undefined") return;
11678
+ const host = typeof window !== "undefined" && typeof window.fetch === "function" ? window : typeof globalThis !== "undefined" && typeof globalThis.fetch === "function" ? globalThis : null;
11679
+ if (!host) return;
11680
+ const canCloneResponse = typeof document !== "undefined";
11681
+ this.fetchHost = host;
11682
+ this.originalFetch = host.fetch;
11542
11683
  const self2 = this;
11543
- window.fetch = async function(input, init) {
11684
+ host.fetch = async function(input, init) {
11544
11685
  const startTime = Date.now();
11545
11686
  const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
11546
11687
  const method = init?.method || "GET";
11547
11688
  try {
11548
- const response = await self2.originalFetch.call(window, input, init);
11689
+ const response = await self2.originalFetch.call(host, input, init);
11549
11690
  const requestEntry = {
11550
11691
  method,
11551
11692
  url: url.slice(0, 200),
@@ -11554,7 +11695,7 @@ var ContextCaptureManager = class {
11554
11695
  duration: Date.now() - startTime,
11555
11696
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
11556
11697
  };
11557
- if (response.status >= 400) {
11698
+ if (canCloneResponse && response.status >= 400) {
11558
11699
  try {
11559
11700
  const cloned = response.clone();
11560
11701
  const body = await cloned.text();
@@ -11579,7 +11720,7 @@ var ContextCaptureManager = class {
11579
11720
  };
11580
11721
  }
11581
11722
  captureNavigation() {
11582
- if (typeof window === "undefined" || typeof history === "undefined") return;
11723
+ if (typeof window === "undefined" || typeof history === "undefined" || !window.location) return;
11583
11724
  this.trackNavigation(window.location.pathname);
11584
11725
  const self2 = this;
11585
11726
  this.originalPushState = history.pushState;
@@ -11617,13 +11758,13 @@ var ContextCaptureManager = class {
11617
11758
  return Object.keys(metrics).length > 0 ? metrics : void 0;
11618
11759
  }
11619
11760
  getEnvironmentInfo() {
11620
- if (typeof window === "undefined" || typeof navigator === "undefined") return void 0;
11761
+ if (typeof window === "undefined" || typeof navigator === "undefined" || typeof document === "undefined") return void 0;
11621
11762
  return {
11622
11763
  language: navigator.language,
11623
11764
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
11624
- cookiesEnabled: navigator.cookieEnabled,
11765
+ cookiesEnabled: navigator.cookieEnabled ?? false,
11625
11766
  localStorage: typeof localStorage !== "undefined",
11626
- online: navigator.onLine
11767
+ online: navigator.onLine ?? true
11627
11768
  };
11628
11769
  }
11629
11770
  };
@@ -11798,29 +11939,140 @@ var formatPgError = (e) => {
11798
11939
  const { message, code, details, hint } = e;
11799
11940
  return { message, code, details, hint };
11800
11941
  };
11942
+ var DEFAULT_API_BASE_URL = "https://app.bugbear.ai";
11943
+ var CONFIG_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
11944
+ var CONFIG_CACHE_PREFIX = "bugbear_config_";
11801
11945
  var BugBearClient = class {
11802
11946
  constructor(config) {
11803
11947
  this.navigationHistory = [];
11804
11948
  this.reportSubmitInFlight = false;
11805
11949
  this._queue = null;
11806
11950
  this.realtimeChannels = [];
11807
- if (!config.supabaseUrl) {
11808
- throw new Error("BugBear: supabaseUrl is required. Get it from your BugBear project settings.");
11809
- }
11810
- if (!config.supabaseAnonKey) {
11811
- throw new Error("BugBear: supabaseAnonKey is required. Get it from your BugBear project settings.");
11812
- }
11951
+ this.initialized = false;
11952
+ this.initError = null;
11813
11953
  this.config = config;
11814
- this.supabase = createClient(config.supabaseUrl, config.supabaseAnonKey);
11815
- if (config.offlineQueue?.enabled) {
11954
+ if (config.apiKey) {
11955
+ this.pendingInit = this.resolveFromApiKey(config.apiKey);
11956
+ } else if (config.supabaseUrl && config.supabaseAnonKey) {
11957
+ if (!config.projectId) {
11958
+ throw new Error(
11959
+ "BugBear: projectId is required when using explicit Supabase credentials. Tip: Use apiKey instead for simpler setup \u2014 it resolves everything automatically."
11960
+ );
11961
+ }
11962
+ this.supabase = createClient(config.supabaseUrl, config.supabaseAnonKey);
11963
+ this.initialized = true;
11964
+ this.pendingInit = Promise.resolve();
11965
+ this.initOfflineQueue();
11966
+ } else {
11967
+ throw new Error(
11968
+ "BugBear: Missing configuration. Provide either:\n \u2022 apiKey (recommended) \u2014 resolves everything automatically\n \u2022 projectId + supabaseUrl + supabaseAnonKey \u2014 explicit credentials\n\nGet your API key at https://app.bugbear.ai/settings/projects"
11969
+ );
11970
+ }
11971
+ }
11972
+ /** Whether the client is ready for requests. */
11973
+ get isReady() {
11974
+ return this.initialized;
11975
+ }
11976
+ /** Wait until the client is ready. Throws if initialization failed. */
11977
+ async ready() {
11978
+ await this.pendingInit;
11979
+ if (this.initError) throw this.initError;
11980
+ }
11981
+ /**
11982
+ * Resolve Supabase credentials from a BugBear API key.
11983
+ * Checks localStorage cache first, falls back to /api/v1/config.
11984
+ */
11985
+ async resolveFromApiKey(apiKey) {
11986
+ try {
11987
+ const cached = this.readConfigCache(apiKey);
11988
+ if (cached) {
11989
+ this.applyResolvedConfig(cached);
11990
+ return;
11991
+ }
11992
+ const baseUrl = (this.config.apiBaseUrl || DEFAULT_API_BASE_URL).replace(/\/$/, "");
11993
+ const response = await fetch(`${baseUrl}/api/v1/config`, {
11994
+ headers: { Authorization: `Bearer ${apiKey}` }
11995
+ });
11996
+ if (!response.ok) {
11997
+ const body = await response.json().catch(() => ({}));
11998
+ const message = body.error || `HTTP ${response.status}`;
11999
+ throw new Error(
12000
+ `BugBear: Invalid API key \u2014 ${message}. Get yours at https://app.bugbear.ai/settings/projects`
12001
+ );
12002
+ }
12003
+ const data = await response.json();
12004
+ this.writeConfigCache(apiKey, data);
12005
+ this.applyResolvedConfig(data);
12006
+ } catch (err) {
12007
+ this.initError = err instanceof Error ? err : new Error(String(err));
12008
+ this.config.onError?.(this.initError, { context: "apikey_resolution_failed" });
12009
+ throw this.initError;
12010
+ }
12011
+ }
12012
+ /** Apply resolved credentials and create the Supabase client. */
12013
+ applyResolvedConfig(resolved) {
12014
+ this.config = {
12015
+ ...this.config,
12016
+ projectId: resolved.projectId,
12017
+ supabaseUrl: resolved.supabaseUrl,
12018
+ supabaseAnonKey: resolved.supabaseAnonKey
12019
+ };
12020
+ this.supabase = createClient(resolved.supabaseUrl, resolved.supabaseAnonKey);
12021
+ this.initialized = true;
12022
+ this.initOfflineQueue();
12023
+ }
12024
+ /** Initialize offline queue if configured. Shared by both init paths. */
12025
+ initOfflineQueue() {
12026
+ if (this.config.offlineQueue?.enabled) {
11816
12027
  this._queue = new OfflineQueue({
11817
12028
  enabled: true,
11818
- maxItems: config.offlineQueue.maxItems,
11819
- maxRetries: config.offlineQueue.maxRetries
12029
+ maxItems: this.config.offlineQueue.maxItems,
12030
+ maxRetries: this.config.offlineQueue.maxRetries
11820
12031
  });
11821
12032
  this.registerQueueHandlers();
11822
12033
  }
11823
12034
  }
12035
+ /** Read cached config from localStorage if available and not expired. */
12036
+ readConfigCache(apiKey) {
12037
+ if (typeof localStorage === "undefined") return null;
12038
+ try {
12039
+ const key = CONFIG_CACHE_PREFIX + this.hashKey(apiKey);
12040
+ const raw = localStorage.getItem(key);
12041
+ if (!raw) return null;
12042
+ const cached = JSON.parse(raw);
12043
+ if (Date.now() - cached.cachedAt > CONFIG_CACHE_TTL_MS) {
12044
+ localStorage.removeItem(key);
12045
+ return null;
12046
+ }
12047
+ return cached;
12048
+ } catch {
12049
+ return null;
12050
+ }
12051
+ }
12052
+ /** Write resolved config to localStorage cache. */
12053
+ writeConfigCache(apiKey, data) {
12054
+ if (typeof localStorage === "undefined") return;
12055
+ try {
12056
+ const key = CONFIG_CACHE_PREFIX + this.hashKey(apiKey);
12057
+ const cached = { ...data, cachedAt: Date.now() };
12058
+ localStorage.setItem(key, JSON.stringify(cached));
12059
+ } catch {
12060
+ }
12061
+ }
12062
+ /** Simple string hash for cache keys — avoids storing raw API keys. */
12063
+ hashKey(apiKey) {
12064
+ let hash = 0;
12065
+ for (let i = 0; i < apiKey.length; i++) {
12066
+ hash = (hash << 5) - hash + apiKey.charCodeAt(i) | 0;
12067
+ }
12068
+ return hash.toString(36);
12069
+ }
12070
+ /** Ensure the client is initialized before making requests. */
12071
+ async ensureReady() {
12072
+ if (this.initialized) return;
12073
+ await this.pendingInit;
12074
+ if (this.initError) throw this.initError;
12075
+ }
11824
12076
  // ── Offline Queue ─────────────────────────────────────────
11825
12077
  /**
11826
12078
  * Access the offline queue (if enabled).
@@ -11976,6 +12228,7 @@ var BugBearClient = class {
11976
12228
  * Get current user info from host app or BugBear's own auth
11977
12229
  */
11978
12230
  async getCurrentUserInfo() {
12231
+ await this.ensureReady();
11979
12232
  if (this.config.getCurrentUser) {
11980
12233
  return await this.config.getCurrentUser();
11981
12234
  }
@@ -12195,6 +12448,7 @@ var BugBearClient = class {
12195
12448
  */
12196
12449
  async getAssignment(assignmentId) {
12197
12450
  try {
12451
+ await this.ensureReady();
12198
12452
  const { data, error } = await this.supabase.from("test_assignments").select(`
12199
12453
  id,
12200
12454
  status,
@@ -12266,6 +12520,7 @@ var BugBearClient = class {
12266
12520
  */
12267
12521
  async updateAssignmentStatus(assignmentId, status, options) {
12268
12522
  try {
12523
+ await this.ensureReady();
12269
12524
  const { data: currentAssignment, error: fetchError } = await this.supabase.from("test_assignments").select("status, started_at").eq("id", assignmentId).single();
12270
12525
  if (fetchError || !currentAssignment) {
12271
12526
  console.error("BugBear: Assignment not found", {
@@ -12352,6 +12607,7 @@ var BugBearClient = class {
12352
12607
  */
12353
12608
  async reopenAssignment(assignmentId) {
12354
12609
  try {
12610
+ await this.ensureReady();
12355
12611
  const { data: current, error: fetchError } = await this.supabase.from("test_assignments").select("status").eq("id", assignmentId).single();
12356
12612
  if (fetchError || !current) {
12357
12613
  return { success: false, error: "Assignment not found" };
@@ -12391,6 +12647,7 @@ var BugBearClient = class {
12391
12647
  actualNotes = notes;
12392
12648
  }
12393
12649
  try {
12650
+ await this.ensureReady();
12394
12651
  const updateData = {
12395
12652
  status: "skipped",
12396
12653
  skip_reason: actualReason,
@@ -12560,6 +12817,7 @@ var BugBearClient = class {
12560
12817
  */
12561
12818
  async getTesterInfo() {
12562
12819
  try {
12820
+ await this.ensureReady();
12563
12821
  const userInfo = await this.getCurrentUserInfo();
12564
12822
  if (!userInfo?.email) return null;
12565
12823
  if (!this.isValidEmail(userInfo.email)) {
@@ -12851,6 +13109,7 @@ var BugBearClient = class {
12851
13109
  */
12852
13110
  async isQAEnabled() {
12853
13111
  try {
13112
+ await this.ensureReady();
12854
13113
  const { data, error } = await this.supabase.rpc("check_qa_enabled", {
12855
13114
  p_project_id: this.config.projectId
12856
13115
  });
@@ -12882,6 +13141,7 @@ var BugBearClient = class {
12882
13141
  */
12883
13142
  async uploadScreenshot(file, filename, bucket = "screenshots") {
12884
13143
  try {
13144
+ await this.ensureReady();
12885
13145
  const contentType = file.type || "image/png";
12886
13146
  const ext = contentType.includes("png") ? "png" : "jpg";
12887
13147
  const name = filename || `screenshot-${Date.now()}.${ext}`;
@@ -12922,6 +13182,7 @@ var BugBearClient = class {
12922
13182
  */
12923
13183
  async uploadImageFromUri(uri, filename, bucket = "screenshots") {
12924
13184
  try {
13185
+ await this.ensureReady();
12925
13186
  const response = await fetch(uri);
12926
13187
  const blob = await response.blob();
12927
13188
  const contentType = blob.type || "image/jpeg";
@@ -12967,15 +13228,18 @@ var BugBearClient = class {
12967
13228
  * Get device info (override in platform-specific implementations)
12968
13229
  */
12969
13230
  getDeviceInfo() {
12970
- if (typeof window !== "undefined") {
12971
- return {
12972
- platform: "web",
12973
- userAgent: navigator.userAgent,
12974
- screenSize: {
13231
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
13232
+ const info = { platform: "web" };
13233
+ if (typeof navigator !== "undefined" && navigator.userAgent) {
13234
+ info.userAgent = navigator.userAgent;
13235
+ }
13236
+ if (window.screen) {
13237
+ info.screenSize = {
12975
13238
  width: window.screen.width,
12976
13239
  height: window.screen.height
12977
- }
12978
- };
13240
+ };
13241
+ }
13242
+ return info;
12979
13243
  }
12980
13244
  return { platform: "web" };
12981
13245
  }
@@ -13013,6 +13277,7 @@ var BugBearClient = class {
13013
13277
  */
13014
13278
  async getFixRequests(options) {
13015
13279
  try {
13280
+ await this.ensureReady();
13016
13281
  let query = this.supabase.from("fix_requests").select("*").eq("project_id", this.config.projectId).order("created_at", { ascending: false }).limit(options?.limit || 20);
13017
13282
  if (options?.status) {
13018
13283
  query = query.eq("status", options.status);
@@ -13084,6 +13349,7 @@ var BugBearClient = class {
13084
13349
  */
13085
13350
  async getThreadMessages(threadId) {
13086
13351
  try {
13352
+ await this.ensureReady();
13087
13353
  const { data, error } = await this.supabase.from("discussion_messages").select(`
13088
13354
  id,
13089
13355
  thread_id,
@@ -13286,6 +13552,7 @@ var BugBearClient = class {
13286
13552
  */
13287
13553
  async endSession(sessionId, options = {}) {
13288
13554
  try {
13555
+ await this.ensureReady();
13289
13556
  const { data, error } = await this.supabase.rpc("end_qa_session", {
13290
13557
  p_session_id: sessionId,
13291
13558
  p_notes: options.notes || null,
@@ -13323,6 +13590,7 @@ var BugBearClient = class {
13323
13590
  */
13324
13591
  async getSession(sessionId) {
13325
13592
  try {
13593
+ await this.ensureReady();
13326
13594
  const { data, error } = await this.supabase.from("qa_sessions").select("*").eq("id", sessionId).single();
13327
13595
  if (error || !data) return null;
13328
13596
  return this.transformSession(data);
@@ -13354,6 +13622,7 @@ var BugBearClient = class {
13354
13622
  */
13355
13623
  async addFinding(sessionId, options) {
13356
13624
  try {
13625
+ await this.ensureReady();
13357
13626
  const { data, error } = await this.supabase.rpc("add_session_finding", {
13358
13627
  p_session_id: sessionId,
13359
13628
  p_type: options.type,
@@ -13384,6 +13653,7 @@ var BugBearClient = class {
13384
13653
  */
13385
13654
  async getSessionFindings(sessionId) {
13386
13655
  try {
13656
+ await this.ensureReady();
13387
13657
  const { data, error } = await this.supabase.from("qa_findings").select("*").eq("session_id", sessionId).order("created_at", { ascending: true }).limit(100);
13388
13658
  if (error) {
13389
13659
  console.error("BugBear: Failed to fetch findings", formatPgError(error));
@@ -13400,6 +13670,7 @@ var BugBearClient = class {
13400
13670
  */
13401
13671
  async convertFindingToBug(findingId) {
13402
13672
  try {
13673
+ await this.ensureReady();
13403
13674
  const { data, error } = await this.supabase.rpc("convert_finding_to_bug", {
13404
13675
  p_finding_id: findingId
13405
13676
  });
@@ -13419,6 +13690,7 @@ var BugBearClient = class {
13419
13690
  */
13420
13691
  async dismissFinding(findingId, reason) {
13421
13692
  try {
13693
+ await this.ensureReady();
13422
13694
  const { error } = await this.supabase.from("qa_findings").update({
13423
13695
  dismissed: true,
13424
13696
  dismissed_reason: reason || null,
@@ -14970,9 +15242,9 @@ function TestListScreen({ nav }) {
14970
15242
  /* @__PURE__ */ import_react6.default.createElement(import_react_native6.Text, { style: [styles3.trackBtnText, isActive && { color: track.color, fontWeight: "600" }] }, track.icon, " ", track.name)
14971
15243
  );
14972
15244
  })), /* @__PURE__ */ import_react6.default.createElement(import_react_native6.View, { style: styles3.sortGroup }, [
14973
- { key: "priority", label: "\u2195" },
14974
- { key: "recent", label: "\u{1F550}" },
14975
- { key: "alpha", label: "AZ" }
15245
+ { key: "priority", label: "\u2195 Priority" },
15246
+ { key: "recent", label: "\u{1F550} Recent" },
15247
+ { key: "alpha", label: "A-Z" }
14976
15248
  ].map((s2) => /* @__PURE__ */ import_react6.default.createElement(
14977
15249
  import_react_native6.TouchableOpacity,
14978
15250
  {
@@ -16189,8 +16461,9 @@ var styles13 = import_react_native16.StyleSheet.create({
16189
16461
  // src/widget/screens/IssueListScreen.tsx
16190
16462
  var import_react18 = __toESM(require("react"));
16191
16463
  var import_react_native17 = require("react-native");
16464
+ var CATEGORIES = ["open", "done", "reopened"];
16192
16465
  var CATEGORY_CONFIG = {
16193
- open: { label: "Open Issues", accent: "#f97316", emptyIcon: "\u2705", emptyText: "No open issues" },
16466
+ open: { label: "Open", accent: "#f97316", emptyIcon: "\u2705", emptyText: "No open issues" },
16194
16467
  done: { label: "Done", accent: "#22c55e", emptyIcon: "\u{1F389}", emptyText: "No completed issues yet" },
16195
16468
  reopened: { label: "Reopened", accent: "#ef4444", emptyIcon: "\u{1F44D}", emptyText: "No reopened issues" }
16196
16469
  };
@@ -16200,11 +16473,20 @@ var SEVERITY_COLORS = {
16200
16473
  medium: "#eab308",
16201
16474
  low: "#71717a"
16202
16475
  };
16476
+ var SEVERITY_ORDER = { critical: 0, high: 1, medium: 2, low: 3 };
16203
16477
  function IssueListScreen({ nav, category }) {
16204
16478
  const { client } = useBugBear();
16479
+ const [activeCategory, setActiveCategory] = (0, import_react18.useState)(category);
16205
16480
  const [issues, setIssues] = (0, import_react18.useState)([]);
16206
16481
  const [loading, setLoading] = (0, import_react18.useState)(true);
16207
- const config = CATEGORY_CONFIG[category];
16482
+ const [counts, setCounts] = (0, import_react18.useState)(null);
16483
+ const [sortMode, setSortMode] = (0, import_react18.useState)("severity");
16484
+ const config = CATEGORY_CONFIG[activeCategory];
16485
+ (0, import_react18.useEffect)(() => {
16486
+ if (!client) return;
16487
+ client.getIssueCounts().then(setCounts).catch(() => {
16488
+ });
16489
+ }, [client]);
16208
16490
  (0, import_react18.useEffect)(() => {
16209
16491
  let cancelled = false;
16210
16492
  setLoading(true);
@@ -16214,7 +16496,7 @@ function IssueListScreen({ nav, category }) {
16214
16496
  return;
16215
16497
  }
16216
16498
  try {
16217
- const data = await client.getIssues(category);
16499
+ const data = await client.getIssues(activeCategory);
16218
16500
  if (!cancelled) {
16219
16501
  setIssues(data);
16220
16502
  }
@@ -16229,14 +16511,63 @@ function IssueListScreen({ nav, category }) {
16229
16511
  return () => {
16230
16512
  cancelled = true;
16231
16513
  };
16232
- }, [client, category]);
16233
- if (loading) {
16234
- return /* @__PURE__ */ import_react18.default.createElement(IssueListScreenSkeleton, null);
16235
- }
16236
- if (issues.length === 0) {
16237
- return /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles14.emptyContainer }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles14.emptyIcon }, config.emptyIcon), /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles14.emptyText }, config.emptyText));
16238
- }
16239
- return /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, null, issues.map((issue) => /* @__PURE__ */ import_react18.default.createElement(
16514
+ }, [client, activeCategory]);
16515
+ const sortedIssues = (0, import_react18.useMemo)(() => {
16516
+ const sorted = [...issues];
16517
+ if (sortMode === "severity") {
16518
+ sorted.sort((a, b) => (SEVERITY_ORDER[a.severity || "low"] ?? 4) - (SEVERITY_ORDER[b.severity || "low"] ?? 4));
16519
+ } else {
16520
+ sorted.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
16521
+ }
16522
+ return sorted;
16523
+ }, [issues, sortMode]);
16524
+ return /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, null, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles14.tabBar }, CATEGORIES.map((cat) => {
16525
+ const catConfig = CATEGORY_CONFIG[cat];
16526
+ const isActive = activeCategory === cat;
16527
+ const count = counts?.[cat];
16528
+ return /* @__PURE__ */ import_react18.default.createElement(
16529
+ import_react_native17.TouchableOpacity,
16530
+ {
16531
+ key: cat,
16532
+ style: [
16533
+ styles14.tab,
16534
+ { borderBottomColor: isActive ? catConfig.accent : "transparent" }
16535
+ ],
16536
+ onPress: () => setActiveCategory(cat),
16537
+ activeOpacity: 0.7
16538
+ },
16539
+ /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: [
16540
+ styles14.tabLabel,
16541
+ isActive && { fontWeight: "600", color: colors.textPrimary }
16542
+ ] }, catConfig.label),
16543
+ count !== void 0 && /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: [
16544
+ styles14.countBadge,
16545
+ {
16546
+ backgroundColor: isActive ? catConfig.accent + "18" : colors.card
16547
+ }
16548
+ ] }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: [
16549
+ styles14.countText,
16550
+ { color: isActive ? catConfig.accent : colors.textDim }
16551
+ ] }, count))
16552
+ );
16553
+ })), /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles14.sortRow }, [
16554
+ { key: "severity", label: "Severity" },
16555
+ { key: "recent", label: "Recent" }
16556
+ ].map((s2) => /* @__PURE__ */ import_react18.default.createElement(
16557
+ import_react_native17.TouchableOpacity,
16558
+ {
16559
+ key: s2.key,
16560
+ style: [
16561
+ styles14.sortBtn,
16562
+ sortMode === s2.key && styles14.sortBtnActive
16563
+ ],
16564
+ onPress: () => setSortMode(s2.key)
16565
+ },
16566
+ /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: [
16567
+ styles14.sortBtnText,
16568
+ sortMode === s2.key && styles14.sortBtnTextActive
16569
+ ] }, s2.label)
16570
+ ))), loading ? /* @__PURE__ */ import_react18.default.createElement(IssueListScreenSkeleton, null) : sortedIssues.length === 0 ? /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles14.emptyContainer }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles14.emptyIcon }, config.emptyIcon), /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles14.emptyText }, config.emptyText)) : sortedIssues.map((issue) => /* @__PURE__ */ import_react18.default.createElement(
16240
16571
  import_react_native17.TouchableOpacity,
16241
16572
  {
16242
16573
  key: issue.id,
@@ -16246,11 +16577,69 @@ function IssueListScreen({ nav, category }) {
16246
16577
  },
16247
16578
  /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles14.topRow }, issue.severity && /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: [styles14.severityDot, { backgroundColor: SEVERITY_COLORS[issue.severity] || colors.textDim }] }), /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles14.issueTitle, numberOfLines: 1 }, issue.title)),
16248
16579
  /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles14.bottomRow }, issue.route && /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles14.routeText, numberOfLines: 1 }, issue.route), /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles14.timeText }, formatRelativeTime(issue.updatedAt))),
16249
- category === "done" && issue.verifiedByName && /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles14.verifiedBadge }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles14.verifiedBadgeText }, "\u2714", " Verified by ", issue.verifiedByName)),
16250
- category === "reopened" && issue.originalBugTitle && /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles14.reopenedBadge }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles14.reopenedBadgeText, numberOfLines: 1 }, "\u{1F504}", " Retest of: ", issue.originalBugTitle))
16580
+ activeCategory === "done" && issue.verifiedByName && /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles14.verifiedBadge }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles14.verifiedBadgeText }, "\u2714", " Verified by ", issue.verifiedByName)),
16581
+ activeCategory === "reopened" && issue.originalBugTitle && /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles14.reopenedBadge }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles14.reopenedBadgeText, numberOfLines: 1 }, "\u{1F504}", " Retest of: ", issue.originalBugTitle))
16251
16582
  )));
16252
16583
  }
16253
16584
  var styles14 = import_react_native17.StyleSheet.create({
16585
+ tabBar: {
16586
+ flexDirection: "row",
16587
+ borderBottomWidth: 1,
16588
+ borderBottomColor: colors.border,
16589
+ marginBottom: 8
16590
+ },
16591
+ tab: {
16592
+ flex: 1,
16593
+ flexDirection: "row",
16594
+ alignItems: "center",
16595
+ justifyContent: "center",
16596
+ gap: 6,
16597
+ paddingVertical: 8,
16598
+ paddingHorizontal: 4,
16599
+ borderBottomWidth: 2
16600
+ },
16601
+ tabLabel: {
16602
+ fontSize: 12,
16603
+ fontWeight: "400",
16604
+ color: colors.textMuted
16605
+ },
16606
+ countBadge: {
16607
+ borderRadius: 8,
16608
+ paddingHorizontal: 6,
16609
+ paddingVertical: 1,
16610
+ minWidth: 18,
16611
+ alignItems: "center"
16612
+ },
16613
+ countText: {
16614
+ fontSize: 10,
16615
+ fontWeight: "600"
16616
+ },
16617
+ sortRow: {
16618
+ flexDirection: "row",
16619
+ justifyContent: "flex-end",
16620
+ gap: 2,
16621
+ marginBottom: 8
16622
+ },
16623
+ sortBtn: {
16624
+ paddingHorizontal: 8,
16625
+ paddingVertical: 3,
16626
+ borderRadius: 6,
16627
+ borderWidth: 1,
16628
+ borderColor: "transparent"
16629
+ },
16630
+ sortBtnActive: {
16631
+ backgroundColor: colors.card,
16632
+ borderColor: colors.border
16633
+ },
16634
+ sortBtnText: {
16635
+ fontSize: 10,
16636
+ fontWeight: "400",
16637
+ color: colors.textMuted
16638
+ },
16639
+ sortBtnTextActive: {
16640
+ fontWeight: "600",
16641
+ color: colors.textPrimary
16642
+ },
16254
16643
  emptyContainer: {
16255
16644
  alignItems: "center",
16256
16645
  paddingVertical: 40