@palbase/web 1.9.0 → 2.0.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.
- package/README.md +3 -2
- package/dist/{analytics-facade-DsvKx5A5.d.ts → analytics-facade-DMtGDGfd.d.ts} +3 -19
- package/dist/{analytics-facade-DFd5LB3_.d.cts → analytics-facade-ovP0pF2P.d.cts} +3 -19
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/{chunk-I3ZMB7XM.js → chunk-V6VTX65P.js} +23 -36
- package/dist/chunk-V6VTX65P.js.map +1 -0
- package/dist/gen/cli.cjs +1228 -0
- package/dist/gen/cli.cjs.map +1 -0
- package/dist/gen/cli.d.cts +1 -0
- package/dist/gen/cli.d.ts +1 -0
- package/dist/gen/cli.js +1206 -0
- package/dist/gen/cli.js.map +1 -0
- package/dist/index.cjs +18 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -1
- package/dist/internal.cjs +19 -30
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +3 -3
- package/dist/internal.d.ts +3 -3
- package/dist/internal.js +2 -1
- package/dist/next/client.cjs +16 -29
- package/dist/next/client.cjs.map +1 -1
- package/dist/next/client.js +2 -1
- package/dist/next/client.js.map +1 -1
- package/dist/next/index.cjs +19 -30
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +2 -2
- package/dist/next/index.d.ts +2 -2
- package/dist/next/index.js +2 -1
- package/dist/next/index.js.map +1 -1
- package/dist/{pb-CDVMy1l1.d.ts → pb-CvpcQero.d.ts} +1 -1
- package/dist/{pb-D_fuhafL.d.cts → pb-DDM_mCQB.d.cts} +1 -1
- package/dist/react/index.cjs +12 -8
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +2 -1
- package/dist/react/index.js.map +1 -1
- package/package.json +7 -3
- package/dist/chunk-I3ZMB7XM.js.map +0 -1
package/dist/next/client.js
CHANGED
package/dist/next/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/next/client.ts"],"sourcesContent":["/**\n * '@palbase/web/next/client' — the browser half of the Next.js adapter. This entry\n * must NEVER import 'next' (it runs in plain client bundles); the cookie jar\n * is document.cookie itself, written with the shared codec so the server\n * side (pbServer / middleware / callback) reads the same bytes.\n */\nimport { __configure, getRuntime } from '../internal.js';\nimport type { PersistedSession, SessionStorageAdapter } from '../storage.js';\nimport {\n clearedSessionCookieNames,\n decodeSessionCookies,\n encodeSessionCookies,\n endpointRefFromApiKey,\n} from './cookie-codec.js';\n\n/** 30 days — the refresh-token TTL (P3 design contract). */\nconst SESSION_MAX_AGE_S = 2_592_000;\n\n// Secure is unconditional, INCLUDING http://localhost: browsers treat\n// localhost as a potentially-trustworthy origin, so document.cookie accepts\n// Secure cookies there — no dev-mode special case needed. KNOWN LIMITATION:\n// plain-http origins OTHER than localhost — e.g. LAN-IP device testing on\n// http://192.168.x.x — are NOT trustworthy, so the browser silently DROPS\n// these Secure cookie writes and the session won't persist; use https (or a\n// localhost tunnel/port-forward) for on-device testing. NOT HttpOnly by\n// design: the browser SDK must read/write the session (Supabase-paradigm\n// tradeoff, documented in the P3 plan).\nconst WRITE_ATTRS = 'Path=/; SameSite=Lax; Secure';\n\n/** Parse document.cookie (\"a=1; b=2\") into a name → raw-value map. */\nfunction cookieJar(): Map<string, string> {\n const jar = new Map<string, string>();\n for (const part of document.cookie.split(';')) {\n const eq = part.indexOf('=');\n if (eq === -1) continue;\n const name = part.slice(0, eq).trim();\n if (name) jar.set(name, part.slice(eq + 1).trim());\n }\n return jar;\n}\n\nfunction deleteCookie(name: string): void {\n // biome-ignore lint/suspicious/noDocumentCookie: SessionStorageAdapter is a SYNC contract; the async Cookie Store API can't back it (and isn't universal).\n document.cookie = `${name}=; ${WRITE_ATTRS}; Max-Age=0`;\n}\n\n/**\n * document.cookie-backed SessionStorageAdapter. `load` returns the EXTENDED\n * PersistedSession (access token + expiry ride along) so hydration adopts\n * the full session without a refresh round-trip.\n */\nexport function cookieSessionStorage(endpointRef: string): SessionStorageAdapter {\n return {\n load(): PersistedSession | null {\n if (typeof document === 'undefined') return null;\n const jar = cookieJar();\n const stored = decodeSessionCookies((name) => jar.get(name), endpointRef);\n if (!stored) return null;\n // A refresh-only save round-trips as a:'' / e:0 — normalize back to\n // the legacy shape so hydration takes the expired-trick path cleanly.\n return stored.accessToken && stored.expiresAt > 0\n ? {\n refreshToken: stored.refreshToken,\n accessToken: stored.accessToken,\n expiresAt: stored.expiresAt,\n }\n : { refreshToken: stored.refreshToken };\n },\n save(session: PersistedSession): void {\n if (typeof document === 'undefined') return;\n const jar = cookieJar();\n // Delete every currently-present session cookie first (stale chunks of\n // a previously-larger session, or a stale base when the new write\n // chunks), then set the new cookie(s).\n for (const name of clearedSessionCookieNames(endpointRef, (n) => jar.has(n))) {\n deleteCookie(name);\n }\n const { set, clear } = encodeSessionCookies(endpointRef, {\n accessToken: session.accessToken ?? '',\n refreshToken: session.refreshToken,\n expiresAt: session.expiresAt ?? 0,\n });\n for (const { name, value } of set) {\n // biome-ignore lint/suspicious/noDocumentCookie: SessionStorageAdapter is a SYNC contract; the async Cookie Store API can't back it (and isn't universal).\n document.cookie = `${name}=${value}; ${WRITE_ATTRS}; Max-Age=${SESSION_MAX_AGE_S}`;\n }\n // Overflow guard (codec contract): delete one-past-the-end so a stale\n // orphan chunk behind a gap can never join a future chunk run.\n for (const name of clear) deleteCookie(name);\n },\n clear(): void {\n if (typeof document === 'undefined') return;\n const jar = cookieJar();\n for (const name of clearedSessionCookieNames(endpointRef, (n) => jar.has(n))) {\n deleteCookie(name);\n }\n },\n };\n}\n\n/**\n * One-liner for a client component/provider: re-configure the already-loaded\n * gen config (palbe.gen.ts must be imported first — throws the guided\n * notConfigured error otherwise) with cookie-backed session storage so the\n * browser and the server share the session. Calling it again simply\n * re-configures (safe, e.g. under fast refresh). When Next evaluates the\n * client component module server-side there is no document — no-op.\n */\nexport function setupPalbeNext(): void {\n if (typeof document === 'undefined') return;\n const config = getRuntime().config;\n __configure({ ...config, storage: cookieSessionStorage(endpointRefFromApiKey(config.apiKey)) });\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/next/client.ts"],"sourcesContent":["/**\n * '@palbase/web/next/client' — the browser half of the Next.js adapter. This entry\n * must NEVER import 'next' (it runs in plain client bundles); the cookie jar\n * is document.cookie itself, written with the shared codec so the server\n * side (pbServer / middleware / callback) reads the same bytes.\n */\nimport { __configure, getRuntime } from '../internal.js';\nimport type { PersistedSession, SessionStorageAdapter } from '../storage.js';\nimport {\n clearedSessionCookieNames,\n decodeSessionCookies,\n encodeSessionCookies,\n endpointRefFromApiKey,\n} from './cookie-codec.js';\n\n/** 30 days — the refresh-token TTL (P3 design contract). */\nconst SESSION_MAX_AGE_S = 2_592_000;\n\n// Secure is unconditional, INCLUDING http://localhost: browsers treat\n// localhost as a potentially-trustworthy origin, so document.cookie accepts\n// Secure cookies there — no dev-mode special case needed. KNOWN LIMITATION:\n// plain-http origins OTHER than localhost — e.g. LAN-IP device testing on\n// http://192.168.x.x — are NOT trustworthy, so the browser silently DROPS\n// these Secure cookie writes and the session won't persist; use https (or a\n// localhost tunnel/port-forward) for on-device testing. NOT HttpOnly by\n// design: the browser SDK must read/write the session (Supabase-paradigm\n// tradeoff, documented in the P3 plan).\nconst WRITE_ATTRS = 'Path=/; SameSite=Lax; Secure';\n\n/** Parse document.cookie (\"a=1; b=2\") into a name → raw-value map. */\nfunction cookieJar(): Map<string, string> {\n const jar = new Map<string, string>();\n for (const part of document.cookie.split(';')) {\n const eq = part.indexOf('=');\n if (eq === -1) continue;\n const name = part.slice(0, eq).trim();\n if (name) jar.set(name, part.slice(eq + 1).trim());\n }\n return jar;\n}\n\nfunction deleteCookie(name: string): void {\n // biome-ignore lint/suspicious/noDocumentCookie: SessionStorageAdapter is a SYNC contract; the async Cookie Store API can't back it (and isn't universal).\n document.cookie = `${name}=; ${WRITE_ATTRS}; Max-Age=0`;\n}\n\n/**\n * document.cookie-backed SessionStorageAdapter. `load` returns the EXTENDED\n * PersistedSession (access token + expiry ride along) so hydration adopts\n * the full session without a refresh round-trip.\n */\nexport function cookieSessionStorage(endpointRef: string): SessionStorageAdapter {\n return {\n load(): PersistedSession | null {\n if (typeof document === 'undefined') return null;\n const jar = cookieJar();\n const stored = decodeSessionCookies((name) => jar.get(name), endpointRef);\n if (!stored) return null;\n // A refresh-only save round-trips as a:'' / e:0 — normalize back to\n // the legacy shape so hydration takes the expired-trick path cleanly.\n return stored.accessToken && stored.expiresAt > 0\n ? {\n refreshToken: stored.refreshToken,\n accessToken: stored.accessToken,\n expiresAt: stored.expiresAt,\n }\n : { refreshToken: stored.refreshToken };\n },\n save(session: PersistedSession): void {\n if (typeof document === 'undefined') return;\n const jar = cookieJar();\n // Delete every currently-present session cookie first (stale chunks of\n // a previously-larger session, or a stale base when the new write\n // chunks), then set the new cookie(s).\n for (const name of clearedSessionCookieNames(endpointRef, (n) => jar.has(n))) {\n deleteCookie(name);\n }\n const { set, clear } = encodeSessionCookies(endpointRef, {\n accessToken: session.accessToken ?? '',\n refreshToken: session.refreshToken,\n expiresAt: session.expiresAt ?? 0,\n });\n for (const { name, value } of set) {\n // biome-ignore lint/suspicious/noDocumentCookie: SessionStorageAdapter is a SYNC contract; the async Cookie Store API can't back it (and isn't universal).\n document.cookie = `${name}=${value}; ${WRITE_ATTRS}; Max-Age=${SESSION_MAX_AGE_S}`;\n }\n // Overflow guard (codec contract): delete one-past-the-end so a stale\n // orphan chunk behind a gap can never join a future chunk run.\n for (const name of clear) deleteCookie(name);\n },\n clear(): void {\n if (typeof document === 'undefined') return;\n const jar = cookieJar();\n for (const name of clearedSessionCookieNames(endpointRef, (n) => jar.has(n))) {\n deleteCookie(name);\n }\n },\n };\n}\n\n/**\n * One-liner for a client component/provider: re-configure the already-loaded\n * gen config (palbe.gen.ts must be imported first — throws the guided\n * notConfigured error otherwise) with cookie-backed session storage so the\n * browser and the server share the session. Calling it again simply\n * re-configures (safe, e.g. under fast refresh). When Next evaluates the\n * client component module server-side there is no document — no-op.\n */\nexport function setupPalbeNext(): void {\n if (typeof document === 'undefined') return;\n const config = getRuntime().config;\n __configure({ ...config, storage: cookieSessionStorage(endpointRefFromApiKey(config.apiKey)) });\n}\n"],"mappings":";;;;;;;;;;;;;AAgBA,IAAM,oBAAoB;AAW1B,IAAM,cAAc;AAGpB,SAAS,YAAiC;AACxC,QAAM,MAAM,oBAAI,IAAoB;AACpC,aAAW,QAAQ,SAAS,OAAO,MAAM,GAAG,GAAG;AAC7C,UAAM,KAAK,KAAK,QAAQ,GAAG;AAC3B,QAAI,OAAO,GAAI;AACf,UAAM,OAAO,KAAK,MAAM,GAAG,EAAE,EAAE,KAAK;AACpC,QAAI,KAAM,KAAI,IAAI,MAAM,KAAK,MAAM,KAAK,CAAC,EAAE,KAAK,CAAC;AAAA,EACnD;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAAoB;AAExC,WAAS,SAAS,GAAG,IAAI,MAAM,WAAW;AAC5C;AAOO,SAAS,qBAAqB,aAA4C;AAC/E,SAAO;AAAA,IACL,OAAgC;AAC9B,UAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,YAAM,MAAM,UAAU;AACtB,YAAM,SAAS,qBAAqB,CAAC,SAAS,IAAI,IAAI,IAAI,GAAG,WAAW;AACxE,UAAI,CAAC,OAAQ,QAAO;AAGpB,aAAO,OAAO,eAAe,OAAO,YAAY,IAC5C;AAAA,QACE,cAAc,OAAO;AAAA,QACrB,aAAa,OAAO;AAAA,QACpB,WAAW,OAAO;AAAA,MACpB,IACA,EAAE,cAAc,OAAO,aAAa;AAAA,IAC1C;AAAA,IACA,KAAK,SAAiC;AACpC,UAAI,OAAO,aAAa,YAAa;AACrC,YAAM,MAAM,UAAU;AAItB,iBAAW,QAAQ,0BAA0B,aAAa,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,GAAG;AAC5E,qBAAa,IAAI;AAAA,MACnB;AACA,YAAM,EAAE,KAAK,MAAM,IAAI,qBAAqB,aAAa;AAAA,QACvD,aAAa,QAAQ,eAAe;AAAA,QACpC,cAAc,QAAQ;AAAA,QACtB,WAAW,QAAQ,aAAa;AAAA,MAClC,CAAC;AACD,iBAAW,EAAE,MAAM,MAAM,KAAK,KAAK;AAEjC,iBAAS,SAAS,GAAG,IAAI,IAAI,KAAK,KAAK,WAAW,aAAa,iBAAiB;AAAA,MAClF;AAGA,iBAAW,QAAQ,MAAO,cAAa,IAAI;AAAA,IAC7C;AAAA,IACA,QAAc;AACZ,UAAI,OAAO,aAAa,YAAa;AACrC,YAAM,MAAM,UAAU;AACtB,iBAAW,QAAQ,0BAA0B,aAAa,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,GAAG;AAC5E,qBAAa,IAAI;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AACF;AAUO,SAAS,iBAAuB;AACrC,MAAI,OAAO,aAAa,YAAa;AACrC,QAAM,SAAS,WAAW,EAAE;AAC5B,cAAY,EAAE,GAAG,QAAQ,SAAS,qBAAqB,sBAAsB,OAAO,MAAM,CAAC,EAAE,CAAC;AAChG;","names":[]}
|
package/dist/next/index.cjs
CHANGED
|
@@ -566,12 +566,6 @@ async function palbeRequest(rt, method, path, spec = {}) {
|
|
|
566
566
|
if (MUTATING.has(method) && !callerHasKey) {
|
|
567
567
|
headers["Idempotency-Key"] = crypto.randomUUID();
|
|
568
568
|
}
|
|
569
|
-
if (rt.appIdentifier !== "") {
|
|
570
|
-
const callerHasBundle = Object.keys(headers).some(
|
|
571
|
-
(k) => k.toLowerCase() === "x-palbase-bundle"
|
|
572
|
-
);
|
|
573
|
-
if (!callerHasBundle) headers["X-Palbase-Bundle"] = rt.appIdentifier;
|
|
574
|
-
}
|
|
575
569
|
const attempt = async () => {
|
|
576
570
|
try {
|
|
577
571
|
return await rt.http.request(method, path, {
|
|
@@ -1465,23 +1459,6 @@ var PalbeAnalytics = class {
|
|
|
1465
1459
|
}
|
|
1466
1460
|
};
|
|
1467
1461
|
|
|
1468
|
-
// src/app-config.ts
|
|
1469
|
-
function loadAppConfig(raw) {
|
|
1470
|
-
if (typeof raw !== "object" || raw === null) {
|
|
1471
|
-
throw new Error("app_config_invalid: expected a JSON object");
|
|
1472
|
-
}
|
|
1473
|
-
const r = raw;
|
|
1474
|
-
const str = (k) => typeof r[k] === "string" ? r[k] : "";
|
|
1475
|
-
return { appId: str("app_id"), identifier: str("identifier"), envPreset: str("env_preset") };
|
|
1476
|
-
}
|
|
1477
|
-
function assertOriginMatches(cfg, runtimeOrigin) {
|
|
1478
|
-
if (cfg.identifier === "") return;
|
|
1479
|
-
if (runtimeOrigin === "") return;
|
|
1480
|
-
if (runtimeOrigin !== cfg.identifier) {
|
|
1481
|
-
throw new Error(`app_config_mismatch: expected origin ${cfg.identifier}, got ${runtimeOrigin}`);
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
1462
|
// src/auth-facade.ts
|
|
1486
1463
|
function mapWireUser(raw) {
|
|
1487
1464
|
return {
|
|
@@ -8278,6 +8255,14 @@ function observeWebVitals(record) {
|
|
|
8278
8255
|
};
|
|
8279
8256
|
}
|
|
8280
8257
|
|
|
8258
|
+
// src/runtime-metadata.ts
|
|
8259
|
+
var APP_METADATA_HEADER = "X-Palbase-Bundle";
|
|
8260
|
+
function applyBrowserOriginHeader(headers) {
|
|
8261
|
+
if (Object.keys(headers).some((key) => key.toLowerCase() === "x-palbase-bundle")) return;
|
|
8262
|
+
const origin = typeof window !== "undefined" && typeof window.location !== "undefined" ? window.location.origin : "";
|
|
8263
|
+
if (origin !== "") headers[APP_METADATA_HEADER] = origin;
|
|
8264
|
+
}
|
|
8265
|
+
|
|
8281
8266
|
// src/realtime/anon-token.ts
|
|
8282
8267
|
var REFRESH_SKEW_MS = 6e4;
|
|
8283
8268
|
var AnonTokenProvider = class {
|
|
@@ -8320,11 +8305,16 @@ var AnonTokenProvider = class {
|
|
|
8320
8305
|
*/
|
|
8321
8306
|
async mint() {
|
|
8322
8307
|
const base = this.rt.config.url.replace(/\/+$/, "");
|
|
8308
|
+
const headers = {
|
|
8309
|
+
apikey: this.rt.config.apiKey,
|
|
8310
|
+
...this.rt.config.headers
|
|
8311
|
+
};
|
|
8312
|
+
applyBrowserOriginHeader(headers);
|
|
8323
8313
|
let response;
|
|
8324
8314
|
try {
|
|
8325
8315
|
response = await fetch(`${base}/auth/anonymous`, {
|
|
8326
8316
|
method: "POST",
|
|
8327
|
-
headers
|
|
8317
|
+
headers
|
|
8328
8318
|
});
|
|
8329
8319
|
} catch (e) {
|
|
8330
8320
|
throw new BackendError("network", {
|
|
@@ -8965,17 +8955,15 @@ function defaultSessionStorage(key) {
|
|
|
8965
8955
|
}
|
|
8966
8956
|
|
|
8967
8957
|
// src/version.ts
|
|
8968
|
-
var VERSION = "
|
|
8958
|
+
var VERSION = "2.0.0";
|
|
8969
8959
|
|
|
8970
8960
|
// src/runtime.ts
|
|
8971
8961
|
function buildRuntime(config) {
|
|
8972
|
-
const appIdentifier = config.identifier ?? "";
|
|
8973
|
-
const runtimeOrigin = typeof window !== "undefined" && typeof window.location !== "undefined" ? window.location.origin : "";
|
|
8974
|
-
assertOriginMatches(loadAppConfig({ identifier: appIdentifier }), runtimeOrigin);
|
|
8975
8962
|
const http = new HttpClient(config.apiKey, {
|
|
8976
8963
|
url: config.url,
|
|
8977
8964
|
headers: { "X-Client-Info": `palbe-web/${VERSION}`, ...config.headers }
|
|
8978
8965
|
});
|
|
8966
|
+
http.addInterceptor(({ headers }) => applyBrowserOriginHeader(headers));
|
|
8979
8967
|
const tokenManager = new TokenManager();
|
|
8980
8968
|
http.tokenManager = tokenManager;
|
|
8981
8969
|
const authClient = new AuthClient(http, tokenManager);
|
|
@@ -9024,7 +9012,6 @@ function buildRuntime(config) {
|
|
|
9024
9012
|
let perf;
|
|
9025
9013
|
const rt = {
|
|
9026
9014
|
config,
|
|
9027
|
-
appIdentifier,
|
|
9028
9015
|
http,
|
|
9029
9016
|
tokenManager,
|
|
9030
9017
|
authClient,
|
|
@@ -9183,7 +9170,9 @@ async function buildHeaders(rt, extra) {
|
|
|
9183
9170
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
9184
9171
|
const callerHasKey = Object.keys(extra ?? {}).some((k) => k.toLowerCase() === "idempotency-key");
|
|
9185
9172
|
if (!callerHasKey) headers["Idempotency-Key"] = crypto.randomUUID();
|
|
9186
|
-
|
|
9173
|
+
const merged = { ...headers, ...extra };
|
|
9174
|
+
applyBrowserOriginHeader(merged);
|
|
9175
|
+
return merged;
|
|
9187
9176
|
}
|
|
9188
9177
|
function buildForm(options) {
|
|
9189
9178
|
const form = new FormData();
|