@palbase/web 4.0.1 → 4.0.2

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 (38) hide show
  1. package/dist/{analytics-facade-DwOtlXPP.d.cts → analytics-facade-CaluA4bW.d.cts} +26 -1
  2. package/dist/{analytics-facade-Nk6J9Ncm.d.ts → analytics-facade-Cp3d4QI-.d.ts} +26 -1
  3. package/dist/{chunk-NXEPAEF5.js → chunk-CFDU23TB.js} +3 -3
  4. package/dist/chunk-CFDU23TB.js.map +1 -0
  5. package/dist/{chunk-TGDS6VMT.js → chunk-TW6YN354.js} +58 -6
  6. package/dist/chunk-TW6YN354.js.map +1 -0
  7. package/dist/gen/cli.cjs +5 -5
  8. package/dist/gen/cli.cjs.map +1 -1
  9. package/dist/gen/cli.js +5 -5
  10. package/dist/gen/cli.js.map +1 -1
  11. package/dist/index.cjs +55 -3
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +3 -3
  14. package/dist/index.d.ts +3 -3
  15. package/dist/index.js +2 -2
  16. package/dist/internal.cjs +57 -5
  17. package/dist/internal.cjs.map +1 -1
  18. package/dist/internal.d.cts +3 -3
  19. package/dist/internal.d.ts +3 -3
  20. package/dist/internal.js +2 -2
  21. package/dist/next/client.cjs +57 -5
  22. package/dist/next/client.cjs.map +1 -1
  23. package/dist/next/client.js +2 -2
  24. package/dist/next/index.cjs +58 -6
  25. package/dist/next/index.cjs.map +1 -1
  26. package/dist/next/index.d.cts +2 -2
  27. package/dist/next/index.d.ts +2 -2
  28. package/dist/next/index.js +2 -2
  29. package/dist/{pb-FG_nV7NR.d.ts → pb-DUK5qy81.d.ts} +1 -1
  30. package/dist/{pb-C9v5dEO6.d.cts → pb-DvV6ftmf.d.cts} +1 -1
  31. package/dist/react/index.cjs +10 -2
  32. package/dist/react/index.cjs.map +1 -1
  33. package/dist/react/index.d.cts +1 -1
  34. package/dist/react/index.d.ts +1 -1
  35. package/dist/react/index.js +2 -2
  36. package/package.json +2 -2
  37. package/dist/chunk-NXEPAEF5.js.map +0 -1
  38. package/dist/chunk-TGDS6VMT.js.map +0 -1
@@ -1,7 +1,7 @@
1
- import { P as PalbeConfig } from './analytics-facade-DwOtlXPP.cjs';
2
- export { d as PalbeRuntime, e as buildRuntime } from './analytics-facade-DwOtlXPP.cjs';
1
+ import { P as PalbeConfig } from './analytics-facade-CaluA4bW.cjs';
2
+ export { d as PalbeRuntime, e as buildRuntime } from './analytics-facade-CaluA4bW.cjs';
3
3
  import { B as BackendError } from './errors-fDoNdTrJ.cjs';
4
- export { P as PB, c as createBoundClient } from './pb-C9v5dEO6.cjs';
4
+ export { P as PB, c as createBoundClient } from './pb-DvV6ftmf.cjs';
5
5
  import './storage-BPaeSG8K.cjs';
6
6
  import './pooled-flags-4GtDtsiu.js';
7
7
 
@@ -1,7 +1,7 @@
1
- import { P as PalbeConfig } from './analytics-facade-Nk6J9Ncm.js';
2
- export { d as PalbeRuntime, e as buildRuntime } from './analytics-facade-Nk6J9Ncm.js';
1
+ import { P as PalbeConfig } from './analytics-facade-Cp3d4QI-.js';
2
+ export { d as PalbeRuntime, e as buildRuntime } from './analytics-facade-Cp3d4QI-.js';
3
3
  import { B as BackendError } from './errors-fDoNdTrJ.js';
4
- export { P as PB, c as createBoundClient } from './pb-FG_nV7NR.js';
4
+ export { P as PB, c as createBoundClient } from './pb-DUK5qy81.js';
5
5
  import './storage-BPaeSG8K.js';
6
6
  import './pooled-flags-4GtDtsiu.js';
7
7
 
package/dist/internal.js CHANGED
@@ -6,8 +6,8 @@ import {
6
6
  createBoundClient,
7
7
  getRuntime,
8
8
  onConfigured
9
- } from "./chunk-TGDS6VMT.js";
10
- import "./chunk-NXEPAEF5.js";
9
+ } from "./chunk-TW6YN354.js";
10
+ import "./chunk-CFDU23TB.js";
11
11
  import "./chunk-PZ5AY32C.js";
12
12
  export {
13
13
  __configure,
@@ -50,7 +50,7 @@ var PalbaseError = class extends Error {
50
50
  }
51
51
  };
52
52
  var PALBASE_DEFAULT_HOST = "api.palbase.studio";
53
- var API_KEY_RE = /^pb_([a-z0-9]+)_c[A-Za-z0-9]{20}$/;
53
+ var API_KEY_RE = /^pb_([a-z0-9]{4,24})_c[A-Za-z0-9]{20}$/;
54
54
  function parseEnvironmentRef(apiKey) {
55
55
  return API_KEY_RE.exec(apiKey)?.[1] ?? null;
56
56
  }
@@ -427,6 +427,11 @@ var PERF_EXCLUDED_PREFIX = "/v1/analytics/";
427
427
  function isSelfTraced(path) {
428
428
  return path.startsWith(PERF_EXCLUDED_PREFIX);
429
429
  }
430
+ function isSessionKilled(status, code) {
431
+ if (status === 401) return code === "session_revoked";
432
+ if (status === 403) return code === "subject_fenced" || code === "subject_erased";
433
+ return false;
434
+ }
430
435
  function nowMs() {
431
436
  return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
432
437
  }
@@ -462,7 +467,7 @@ async function palbeRequest(rt, method, path, spec = {}) {
462
467
  let res;
463
468
  try {
464
469
  res = await attempt();
465
- if (res.error?.status === 401 && rt.tokenManager.getRefreshToken() && rt.tokenManager.refreshFunction) {
470
+ if (res.error?.status === 401 && res.error.code !== "session_revoked" && rt.tokenManager.getRefreshToken() && rt.tokenManager.refreshFunction) {
466
471
  try {
467
472
  await rt.tokenManager.refreshSession();
468
473
  } catch (refreshErr) {
@@ -482,6 +487,9 @@ async function palbeRequest(rt, method, path, spec = {}) {
482
487
  if (!isAbort(e)) record(asPalbaseError(e)?.status ?? 0);
483
488
  throw e;
484
489
  }
490
+ if (res.error && isSessionKilled(res.error.status, res.error.code)) {
491
+ rt.auth.reactiveTeardown();
492
+ }
485
493
  record(res.error?.status ?? 200);
486
494
  return unwrap(res);
487
495
  }
@@ -1221,7 +1229,7 @@ var PalbeAnalytics = class {
1221
1229
  };
1222
1230
 
1223
1231
  // src/api-key.ts
1224
- var PUBLISHABLE_API_KEY_RE = /^pb_([a-z0-9]+)_c[A-Za-z0-9]{20}$/;
1232
+ var PUBLISHABLE_API_KEY_RE = /^pb_([a-z0-9]{4,24})_c[A-Za-z0-9]{20}$/;
1225
1233
  function environmentRefFromPublishableApiKey(apiKey) {
1226
1234
  const match = PUBLISHABLE_API_KEY_RE.exec(apiKey);
1227
1235
  return match ? match[1] ?? "" : "";
@@ -1268,7 +1276,8 @@ var PalbeAuth = class {
1268
1276
  if (!this.signedInState) return;
1269
1277
  this.signedInState = false;
1270
1278
  this.cachedUser = null;
1271
- const reason = this.signingOut ? "userInitiated" : "sessionExpired";
1279
+ const reason = this.nextSignOutReason ?? (this.signingOut ? "userInitiated" : "sessionExpired");
1280
+ this.nextSignOutReason = null;
1272
1281
  this.emitState({ status: "signedOut" });
1273
1282
  this.emitEvent({ type: "signedOut", reason });
1274
1283
  } else if (event === "TOKEN_REFRESHED") {
@@ -1281,6 +1290,10 @@ var PalbeAuth = class {
1281
1290
  rt;
1282
1291
  cachedUser = null;
1283
1292
  signingOut = false;
1293
+ // Explicit signedOut reason pinned for the NEXT session clear (deleteAccount /
1294
+ // reactiveTeardown set it before clearSession; the SIGNED_OUT handler consumes
1295
+ // it exactly once, then resets to null → normal signOut/expiry split resumes).
1296
+ nextSignOutReason = null;
1284
1297
  signingIn = false;
1285
1298
  // suppresses AuthClient's TOKEN_REFRESHED during re-signIn
1286
1299
  signedInState = false;
@@ -1328,6 +1341,45 @@ var PalbeAuth = class {
1328
1341
  this.cachedUser = null;
1329
1342
  }
1330
1343
  }
1344
+ /**
1345
+ * Self-service account erasure ("right to be forgotten"). Calls palauth
1346
+ * `DELETE /auth/user` (session-authed + fresh re-auth): password users pass
1347
+ * `{ password }`; passwordless/OAuth users rely on a freshly stepped-up
1348
+ * session. On 202 the erasure workflow is durably queued AND every session is
1349
+ * already revoked server-side — so we tear down local state (mirroring
1350
+ * `signOut()`'s clear, minus the pointless `/logout`) and emit
1351
+ * `signedOut{reason:'accountDeleted'}`.
1352
+ *
1353
+ * On 401 `reauth_required` / 503 `not_configured` (or `erasure_unavailable`)
1354
+ * the request throws BEFORE the teardown line, so the local session is left
1355
+ * fully intact — the deletion did not happen and the user is still signed in.
1356
+ */
1357
+ async deleteAccount(params = {}) {
1358
+ const res = await palbeRequest(this.rt, "DELETE", "/auth/user", {
1359
+ body: params.password ? { password: params.password } : {}
1360
+ });
1361
+ this.nextSignOutReason = "accountDeleted";
1362
+ this.rt.tokenManager.clearSession();
1363
+ this.rt.storage.clear();
1364
+ this.cachedUser = null;
1365
+ return { erasureId: res.erasure_id };
1366
+ }
1367
+ /**
1368
+ * @internal — invoked by the transport choke point (`request.ts`), not app code.
1369
+ * Reactive teardown when the server reports the session is gone: a 403
1370
+ * `subject_fenced`/`subject_erased` (subject being erased) or a 401
1371
+ * `session_revoked`. Clears local state and emits
1372
+ * `signedOut{reason:'sessionInvalid'}` exactly once (deduped by
1373
+ * `signedInState`). An ordinary 403 authz denial does NOT reach here —
1374
+ * `request.ts` matches only the exact session-kill codes.
1375
+ */
1376
+ reactiveTeardown() {
1377
+ if (!this.signedInState) return;
1378
+ this.nextSignOutReason = "sessionInvalid";
1379
+ this.rt.tokenManager.clearSession();
1380
+ this.rt.storage.clear();
1381
+ this.cachedUser = null;
1382
+ }
1331
1383
  async getUser() {
1332
1384
  const raw = await palbeRequest(this.rt, "GET", "/auth/user");
1333
1385
  return mapWireUser(raw);
@@ -8776,7 +8828,7 @@ function defaultSessionStorage(key) {
8776
8828
  }
8777
8829
 
8778
8830
  // src/version.ts
8779
- var VERSION = "4.0.1";
8831
+ var VERSION = "4.0.2";
8780
8832
 
8781
8833
  // src/runtime.ts
8782
8834
  function buildRuntime(config) {