@palbase/web 2.0.1 → 3.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 +11 -9
- package/dist/{analytics-facade-ChlBRcLZ.d.cts → analytics-facade-BOxQ8IP2.d.cts} +8 -16
- package/dist/{analytics-facade-G0il4NrT.d.ts → analytics-facade-yfMJ69vw.d.ts} +8 -16
- package/dist/{chunk-AIPUO4QX.js → chunk-3HVTEZ7N.js} +30 -36
- package/dist/chunk-3HVTEZ7N.js.map +1 -0
- package/dist/{chunk-VJXFABBW.js → chunk-6VGKMNXO.js} +11 -11
- package/dist/chunk-6VGKMNXO.js.map +1 -0
- package/dist/chunk-S7NAY3MW.js +24 -0
- package/dist/chunk-S7NAY3MW.js.map +1 -0
- package/dist/gen/cli.cjs +32 -6
- package/dist/gen/cli.cjs.map +1 -1
- package/dist/gen/cli.js +28 -7
- package/dist/gen/cli.js.map +1 -1
- package/dist/index.cjs +3 -10
- 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 -2
- package/dist/internal.cjs +33 -32
- 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 -2
- package/dist/next/client.cjs +50 -46
- package/dist/next/client.cjs.map +1 -1
- package/dist/next/client.d.cts +1 -1
- package/dist/next/client.d.ts +1 -1
- package/dist/next/client.js +12 -10
- package/dist/next/client.js.map +1 -1
- package/dist/next/index.cjs +53 -47
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +10 -10
- package/dist/next/index.d.ts +10 -10
- package/dist/next/index.js +14 -13
- package/dist/next/index.js.map +1 -1
- package/dist/{pb-B_6o5p79.d.cts → pb-B3h3NIPE.d.cts} +1 -1
- package/dist/{pb-nPBhqhJr.d.ts → pb-QRISxPd1.d.ts} +1 -1
- package/dist/react/index.cjs +1 -1
- 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 -2
- package/package.json +2 -2
- package/dist/chunk-AIPUO4QX.js.map +0 -1
- package/dist/chunk-PZ5AY32C.js +0 -10
- package/dist/chunk-PZ5AY32C.js.map +0 -1
- package/dist/chunk-VJXFABBW.js.map +0 -1
package/dist/next/client.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ import { S as SessionStorageAdapter } from '../storage-BPaeSG8K.cjs';
|
|
|
5
5
|
* PersistedSession (access token + expiry ride along) so hydration adopts
|
|
6
6
|
* the full session without a refresh round-trip.
|
|
7
7
|
*/
|
|
8
|
-
declare function cookieSessionStorage(
|
|
8
|
+
declare function cookieSessionStorage(environmentRef: string): SessionStorageAdapter;
|
|
9
9
|
/**
|
|
10
10
|
* One-liner for a client component/provider: re-configure the already-loaded
|
|
11
11
|
* gen config (palbe.gen.ts must be imported first — throws the guided
|
package/dist/next/client.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { S as SessionStorageAdapter } from '../storage-BPaeSG8K.js';
|
|
|
5
5
|
* PersistedSession (access token + expiry ride along) so hydration adopts
|
|
6
6
|
* the full session without a refresh round-trip.
|
|
7
7
|
*/
|
|
8
|
-
declare function cookieSessionStorage(
|
|
8
|
+
declare function cookieSessionStorage(environmentRef: string): SessionStorageAdapter;
|
|
9
9
|
/**
|
|
10
10
|
* One-liner for a client component/provider: re-configure the already-loaded
|
|
11
11
|
* gen config (palbe.gen.ts must be imported first — throws the guided
|
package/dist/next/client.js
CHANGED
|
@@ -2,13 +2,12 @@ import {
|
|
|
2
2
|
clearedSessionCookieNames,
|
|
3
3
|
decodeSessionCookies,
|
|
4
4
|
encodeSessionCookies
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-6VGKMNXO.js";
|
|
6
6
|
import {
|
|
7
7
|
__configure,
|
|
8
|
-
endpointRefFromApiKey,
|
|
9
8
|
getRuntime
|
|
10
|
-
} from "../chunk-
|
|
11
|
-
import "../chunk-
|
|
9
|
+
} from "../chunk-3HVTEZ7N.js";
|
|
10
|
+
import "../chunk-S7NAY3MW.js";
|
|
12
11
|
|
|
13
12
|
// src/next/client.ts
|
|
14
13
|
var SESSION_MAX_AGE_S = 2592e3;
|
|
@@ -26,12 +25,12 @@ function cookieJar() {
|
|
|
26
25
|
function deleteCookie(name) {
|
|
27
26
|
document.cookie = `${name}=; ${WRITE_ATTRS}; Max-Age=0`;
|
|
28
27
|
}
|
|
29
|
-
function cookieSessionStorage(
|
|
28
|
+
function cookieSessionStorage(environmentRef) {
|
|
30
29
|
return {
|
|
31
30
|
load() {
|
|
32
31
|
if (typeof document === "undefined") return null;
|
|
33
32
|
const jar = cookieJar();
|
|
34
|
-
const stored = decodeSessionCookies((name) => jar.get(name),
|
|
33
|
+
const stored = decodeSessionCookies((name) => jar.get(name), environmentRef);
|
|
35
34
|
if (!stored) return null;
|
|
36
35
|
return stored.accessToken && stored.expiresAt > 0 ? {
|
|
37
36
|
refreshToken: stored.refreshToken,
|
|
@@ -42,10 +41,10 @@ function cookieSessionStorage(endpointRef) {
|
|
|
42
41
|
save(session) {
|
|
43
42
|
if (typeof document === "undefined") return;
|
|
44
43
|
const jar = cookieJar();
|
|
45
|
-
for (const name of clearedSessionCookieNames(
|
|
44
|
+
for (const name of clearedSessionCookieNames(environmentRef, (n) => jar.has(n))) {
|
|
46
45
|
deleteCookie(name);
|
|
47
46
|
}
|
|
48
|
-
const { set, clear } = encodeSessionCookies(
|
|
47
|
+
const { set, clear } = encodeSessionCookies(environmentRef, {
|
|
49
48
|
accessToken: session.accessToken ?? "",
|
|
50
49
|
refreshToken: session.refreshToken,
|
|
51
50
|
expiresAt: session.expiresAt ?? 0
|
|
@@ -58,7 +57,7 @@ function cookieSessionStorage(endpointRef) {
|
|
|
58
57
|
clear() {
|
|
59
58
|
if (typeof document === "undefined") return;
|
|
60
59
|
const jar = cookieJar();
|
|
61
|
-
for (const name of clearedSessionCookieNames(
|
|
60
|
+
for (const name of clearedSessionCookieNames(environmentRef, (n) => jar.has(n))) {
|
|
62
61
|
deleteCookie(name);
|
|
63
62
|
}
|
|
64
63
|
}
|
|
@@ -67,7 +66,10 @@ function cookieSessionStorage(endpointRef) {
|
|
|
67
66
|
function setupPalbeNext() {
|
|
68
67
|
if (typeof document === "undefined") return;
|
|
69
68
|
const config = getRuntime().config;
|
|
70
|
-
__configure({
|
|
69
|
+
__configure({
|
|
70
|
+
...config,
|
|
71
|
+
storage: cookieSessionStorage(config.environmentRef)
|
|
72
|
+
});
|
|
71
73
|
}
|
|
72
74
|
export {
|
|
73
75
|
cookieSessionStorage,
|
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
|
|
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} 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(environmentRef: 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), environmentRef);\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(environmentRef, (n) => jar.has(n))) {\n deleteCookie(name);\n }\n const { set, clear } = encodeSessionCookies(environmentRef, {\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(environmentRef, (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({\n ...config,\n storage: cookieSessionStorage(config.environmentRef),\n });\n}\n"],"mappings":";;;;;;;;;;;;AAeA,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,gBAA+C;AAClF,SAAO;AAAA,IACL,OAAgC;AAC9B,UAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,YAAM,MAAM,UAAU;AACtB,YAAM,SAAS,qBAAqB,CAAC,SAAS,IAAI,IAAI,IAAI,GAAG,cAAc;AAC3E,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,gBAAgB,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,GAAG;AAC/E,qBAAa,IAAI;AAAA,MACnB;AACA,YAAM,EAAE,KAAK,MAAM,IAAI,qBAAqB,gBAAgB;AAAA,QAC1D,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,gBAAgB,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,GAAG;AAC/E,qBAAa,IAAI;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AACF;AAUO,SAAS,iBAAuB;AACrC,MAAI,OAAO,aAAa,YAAa;AACrC,QAAM,SAAS,WAAW,EAAE;AAC5B,cAAY;AAAA,IACV,GAAG;AAAA,IACH,SAAS,qBAAqB,OAAO,cAAc;AAAA,EACrD,CAAC;AACH;","names":[]}
|
package/dist/next/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ __export(next_exports, {
|
|
|
35
35
|
decodeSessionCookies: () => decodeSessionCookies,
|
|
36
36
|
encodeSessionCookies: () => encodeSessionCookies,
|
|
37
37
|
encodeSessionCookiesDecoded: () => encodeSessionCookiesDecoded,
|
|
38
|
-
|
|
38
|
+
environmentRefFromApiKey: () => environmentRefFromApiKey,
|
|
39
39
|
handleAuthCallback: () => handleAuthCallback,
|
|
40
40
|
palbeMiddleware: () => palbeMiddleware,
|
|
41
41
|
pbServer: () => pbServer,
|
|
@@ -57,11 +57,16 @@ function asWireAuthResult(raw) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// src/api-key.ts
|
|
60
|
-
var API_KEY_RE = /^pb_([
|
|
61
|
-
|
|
60
|
+
var API_KEY_RE = /^pb_([a-z0-9]+)_[cs][A-Za-z0-9]{20}$/;
|
|
61
|
+
var PUBLISHABLE_API_KEY_RE = /^pb_([a-z0-9]+)_c[A-Za-z0-9]{20}$/;
|
|
62
|
+
function environmentRefFromApiKey(apiKey) {
|
|
62
63
|
const m = API_KEY_RE.exec(apiKey);
|
|
63
64
|
return m ? m[1] ?? "" : "";
|
|
64
65
|
}
|
|
66
|
+
function environmentRefFromPublishableApiKey(apiKey) {
|
|
67
|
+
const match = PUBLISHABLE_API_KEY_RE.exec(apiKey);
|
|
68
|
+
return match ? match[1] ?? "" : "";
|
|
69
|
+
}
|
|
65
70
|
|
|
66
71
|
// src/next/cookie-codec.ts
|
|
67
72
|
var MAX_COOKIE_VALUE = 3500;
|
|
@@ -71,11 +76,11 @@ var SESSION_COOKIE_ATTRS = {
|
|
|
71
76
|
secure: true,
|
|
72
77
|
maxAge: 2592e3
|
|
73
78
|
};
|
|
74
|
-
function sessionCookieName(
|
|
75
|
-
return `palbe-session-${
|
|
79
|
+
function sessionCookieName(environmentRef) {
|
|
80
|
+
return `palbe-session-${environmentRef}`;
|
|
76
81
|
}
|
|
77
|
-
function encodeSessionCookies(
|
|
78
|
-
const name = sessionCookieName(
|
|
82
|
+
function encodeSessionCookies(environmentRef, session) {
|
|
83
|
+
const name = sessionCookieName(environmentRef);
|
|
79
84
|
const value = encodeURIComponent(
|
|
80
85
|
JSON.stringify({ a: session.accessToken, r: session.refreshToken, e: session.expiresAt })
|
|
81
86
|
);
|
|
@@ -94,15 +99,15 @@ function encodeSessionCookies(endpointRef, session) {
|
|
|
94
99
|
}
|
|
95
100
|
return { set: chunks, clear: [`${name}.${chunks.length}`] };
|
|
96
101
|
}
|
|
97
|
-
function encodeSessionCookiesDecoded(
|
|
98
|
-
const { set, clear } = encodeSessionCookies(
|
|
102
|
+
function encodeSessionCookiesDecoded(environmentRef, session) {
|
|
103
|
+
const { set, clear } = encodeSessionCookies(environmentRef, session);
|
|
99
104
|
return {
|
|
100
105
|
set: set.map(({ name, value }) => ({ name, value: decodeURIComponent(value) })),
|
|
101
106
|
clear
|
|
102
107
|
};
|
|
103
108
|
}
|
|
104
|
-
function decodeSessionCookies(get,
|
|
105
|
-
const base = sessionCookieName(
|
|
109
|
+
function decodeSessionCookies(get, environmentRef) {
|
|
110
|
+
const base = sessionCookieName(environmentRef);
|
|
106
111
|
let encoded = get(base);
|
|
107
112
|
if (encoded === void 0) {
|
|
108
113
|
let joined = "";
|
|
@@ -136,8 +141,8 @@ function parseStoredSession(json) {
|
|
|
136
141
|
return null;
|
|
137
142
|
}
|
|
138
143
|
}
|
|
139
|
-
function clearedSessionCookieNames(
|
|
140
|
-
const base = sessionCookieName(
|
|
144
|
+
function clearedSessionCookieNames(environmentRef, present) {
|
|
145
|
+
const base = sessionCookieName(environmentRef);
|
|
141
146
|
const names = [];
|
|
142
147
|
if (present(base)) names.push(base);
|
|
143
148
|
for (let i = 0; ; i++) {
|
|
@@ -163,18 +168,9 @@ var PalbaseError = class extends Error {
|
|
|
163
168
|
}
|
|
164
169
|
};
|
|
165
170
|
var PALBASE_DEFAULT_HOST = "api.palbase.studio";
|
|
166
|
-
var
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (apiKey.length < 13) return null;
|
|
170
|
-
if (!apiKey.startsWith("pb_")) return null;
|
|
171
|
-
if (apiKey[11] !== "_") return null;
|
|
172
|
-
const ref = apiKey.slice(3, 11);
|
|
173
|
-
if (ref.length !== REF_LEN) return null;
|
|
174
|
-
if (!BASE62_RE.test(ref)) return null;
|
|
175
|
-
const scope = apiKey[12];
|
|
176
|
-
if (scope !== "c") return null;
|
|
177
|
-
return ref;
|
|
171
|
+
var API_KEY_RE2 = /^pb_([a-z0-9]+)_c[A-Za-z0-9]{20}$/;
|
|
172
|
+
function parseEnvironmentRef(apiKey) {
|
|
173
|
+
return API_KEY_RE2.exec(apiKey)?.[1] ?? null;
|
|
178
174
|
}
|
|
179
175
|
var MAX_RETRIES = 3;
|
|
180
176
|
var INITIAL_BACKOFF_MS = 200;
|
|
@@ -204,8 +200,7 @@ var HttpClient = class _HttpClient {
|
|
|
204
200
|
* with the parent at runtime — later changes on the parent propagate to
|
|
205
201
|
* the scope and vice versa.
|
|
206
202
|
*
|
|
207
|
-
* Typical use:
|
|
208
|
-
* gateway can route them to the correct project's data plane.
|
|
203
|
+
* Typical use: adding an Environment-routing header for an admin call.
|
|
209
204
|
*/
|
|
210
205
|
withHeaders(extra) {
|
|
211
206
|
const mergedHeaders = { ...this.options?.headers ?? {}, ...extra };
|
|
@@ -246,10 +241,10 @@ var HttpClient = class _HttpClient {
|
|
|
246
241
|
if (this.options?.url) {
|
|
247
242
|
return this.options.url;
|
|
248
243
|
}
|
|
249
|
-
if (this.apiKey &&
|
|
244
|
+
if (this.apiKey && parseEnvironmentRef(this.apiKey) === null) {
|
|
250
245
|
throw new PalbaseError(
|
|
251
246
|
"invalid_api_key",
|
|
252
|
-
'Invalid API key format. Expected pb_{
|
|
247
|
+
'Invalid API key format. Expected pb_{environment_ref}_c{20_base62_chars}. For dev/staging pass `url: "https://api.dev.palbase.studio"` via options.',
|
|
253
248
|
0
|
|
254
249
|
);
|
|
255
250
|
}
|
|
@@ -262,10 +257,6 @@ var HttpClient = class _HttpClient {
|
|
|
262
257
|
const effectiveKey = this.apiKey;
|
|
263
258
|
if (effectiveKey) {
|
|
264
259
|
headers["apikey"] = effectiveKey;
|
|
265
|
-
const ref = parseProjectRef(effectiveKey);
|
|
266
|
-
if (ref) {
|
|
267
|
-
headers["X-Project-Ref"] = ref;
|
|
268
|
-
}
|
|
269
260
|
}
|
|
270
261
|
const token = this.tokenManager?.getAccessToken();
|
|
271
262
|
if (token) {
|
|
@@ -1245,7 +1236,7 @@ var AnalyticsState = class {
|
|
|
1245
1236
|
idKey;
|
|
1246
1237
|
optOutKey;
|
|
1247
1238
|
constructor(rt) {
|
|
1248
|
-
const ref =
|
|
1239
|
+
const ref = rt.config.environmentRef;
|
|
1249
1240
|
this.idKey = ref ? `palbe.analytics.id.${ref}` : "palbe.analytics.id";
|
|
1250
1241
|
this.optOutKey = ref ? `palbe.analytics.optout.${ref}` : "palbe.analytics.optout";
|
|
1251
1242
|
rt.auth.onAuthEvent((event) => {
|
|
@@ -2586,7 +2577,7 @@ var PalbeFlags = class {
|
|
|
2586
2577
|
constructor(rt) {
|
|
2587
2578
|
this.transport = new FlagsClient(rt.http);
|
|
2588
2579
|
const browser = typeof document !== "undefined";
|
|
2589
|
-
const ref =
|
|
2580
|
+
const ref = rt.config.environmentRef;
|
|
2590
2581
|
const options = {
|
|
2591
2582
|
auth: palbeAuthAdapter(rt.auth),
|
|
2592
2583
|
...ref ? { storageKey: `palbe.flags.${ref}` } : {},
|
|
@@ -8326,7 +8317,7 @@ var AnonTokenProvider = class {
|
|
|
8326
8317
|
}
|
|
8327
8318
|
/**
|
|
8328
8319
|
* Raw fetch, deliberately NOT through HttpClient/palbeRequest: the mint
|
|
8329
|
-
* must carry the
|
|
8320
|
+
* must carry the Environment API key and NEVER a Bearer (iOS keeps
|
|
8330
8321
|
* `/auth/anonymous` on the unauthenticated-path list), and HttpClient's
|
|
8331
8322
|
* pre-flight would try to refresh a stale session before an anon mint —
|
|
8332
8323
|
* exactly the entanglement this provider exists to avoid.
|
|
@@ -8983,10 +8974,25 @@ function defaultSessionStorage(key) {
|
|
|
8983
8974
|
}
|
|
8984
8975
|
|
|
8985
8976
|
// src/version.ts
|
|
8986
|
-
var VERSION = "
|
|
8977
|
+
var VERSION = "3.0.0";
|
|
8987
8978
|
|
|
8988
8979
|
// src/runtime.ts
|
|
8989
8980
|
function buildRuntime(config) {
|
|
8981
|
+
const keyEnvironmentRef = environmentRefFromPublishableApiKey(config.apiKey);
|
|
8982
|
+
if (keyEnvironmentRef === "") {
|
|
8983
|
+
throw new Error("PalbeConfig.apiKey does not contain a valid publishable Environment identity");
|
|
8984
|
+
} else if (config.environmentRef !== keyEnvironmentRef) {
|
|
8985
|
+
throw new Error("PalbeConfig.environmentRef must match the Environment identity in apiKey");
|
|
8986
|
+
}
|
|
8987
|
+
let runtimeURL;
|
|
8988
|
+
try {
|
|
8989
|
+
runtimeURL = new URL(config.url);
|
|
8990
|
+
} catch {
|
|
8991
|
+
throw new Error("PalbeConfig.url must be a valid URL");
|
|
8992
|
+
}
|
|
8993
|
+
if (runtimeURL.hostname.endsWith(".palbase.studio") && runtimeURL.hostname.split(".")[0] !== config.environmentRef) {
|
|
8994
|
+
throw new Error("PalbeConfig.url must match environmentRef for palbase.studio");
|
|
8995
|
+
}
|
|
8990
8996
|
const http = new HttpClient(config.apiKey, {
|
|
8991
8997
|
url: config.url,
|
|
8992
8998
|
headers: { "X-Client-Info": `palbe-web/${VERSION}`, ...config.headers }
|
|
@@ -8995,7 +9001,7 @@ function buildRuntime(config) {
|
|
|
8995
9001
|
const tokenManager = new TokenManager();
|
|
8996
9002
|
http.tokenManager = tokenManager;
|
|
8997
9003
|
const authClient = new AuthClient(http, tokenManager);
|
|
8998
|
-
const ref =
|
|
9004
|
+
const ref = config.environmentRef;
|
|
8999
9005
|
const storage = config.storage ?? defaultSessionStorage(ref ? `palbe.session.${ref}` : void 0);
|
|
9000
9006
|
const persisted = storage.load();
|
|
9001
9007
|
if (persisted) {
|
|
@@ -9449,7 +9455,7 @@ function handleAuthCallback(opts) {
|
|
|
9449
9455
|
const wire = asWireAuthResult(raw);
|
|
9450
9456
|
if (!wire) return redirect(fallback, { auth_error: "oauth_exchange_failed" });
|
|
9451
9457
|
const response = redirect(safeNextPath(params.get("next"), request.nextUrl.origin) ?? fallback);
|
|
9452
|
-
const write = encodeSessionCookiesDecoded(
|
|
9458
|
+
const write = encodeSessionCookiesDecoded(config.environmentRef, {
|
|
9453
9459
|
accessToken: wire.access_token,
|
|
9454
9460
|
refreshToken: wire.refresh_token,
|
|
9455
9461
|
expiresAt: Date.now() + wire.expires_in * 1e3
|
|
@@ -9512,7 +9518,7 @@ async function palbeMiddleware(request, opts) {
|
|
|
9512
9518
|
);
|
|
9513
9519
|
const { NextResponse } = await importNextServer("palbeMiddleware");
|
|
9514
9520
|
const passThrough = () => opts?.response ?? NextResponse.next({ request });
|
|
9515
|
-
const ref =
|
|
9521
|
+
const ref = config.environmentRef;
|
|
9516
9522
|
const session = decodeSessionCookies((name) => request.cookies.get(name)?.value, ref);
|
|
9517
9523
|
if (!session) return passThrough();
|
|
9518
9524
|
if (session.expiresAt - Date.now() > (opts?.refreshMarginMs ?? DEFAULT_REFRESH_MARGIN_MS)) {
|
|
@@ -9582,11 +9588,11 @@ function removeCookie(store, name) {
|
|
|
9582
9588
|
} catch {
|
|
9583
9589
|
}
|
|
9584
9590
|
}
|
|
9585
|
-
function serverCookieAdapter(store,
|
|
9591
|
+
function serverCookieAdapter(store, environmentRef) {
|
|
9586
9592
|
const present = (name) => store.get(name) !== void 0;
|
|
9587
9593
|
return {
|
|
9588
9594
|
load() {
|
|
9589
|
-
const stored = decodeSessionCookies((name) => store.get(name)?.value,
|
|
9595
|
+
const stored = decodeSessionCookies((name) => store.get(name)?.value, environmentRef);
|
|
9590
9596
|
if (!stored) return null;
|
|
9591
9597
|
return stored.accessToken && stored.expiresAt > 0 ? {
|
|
9592
9598
|
refreshToken: stored.refreshToken,
|
|
@@ -9596,10 +9602,10 @@ function serverCookieAdapter(store, endpointRef) {
|
|
|
9596
9602
|
},
|
|
9597
9603
|
save(session) {
|
|
9598
9604
|
if (!session.accessToken || !session.expiresAt) return;
|
|
9599
|
-
for (const name of clearedSessionCookieNames(
|
|
9605
|
+
for (const name of clearedSessionCookieNames(environmentRef, present)) {
|
|
9600
9606
|
removeCookie(store, name);
|
|
9601
9607
|
}
|
|
9602
|
-
const { set, clear } = encodeSessionCookiesDecoded(
|
|
9608
|
+
const { set, clear } = encodeSessionCookiesDecoded(environmentRef, {
|
|
9603
9609
|
accessToken: session.accessToken,
|
|
9604
9610
|
refreshToken: session.refreshToken,
|
|
9605
9611
|
expiresAt: session.expiresAt
|
|
@@ -9613,7 +9619,7 @@ function serverCookieAdapter(store, endpointRef) {
|
|
|
9613
9619
|
for (const name of clear) removeCookie(store, name);
|
|
9614
9620
|
},
|
|
9615
9621
|
clear() {
|
|
9616
|
-
for (const name of clearedSessionCookieNames(
|
|
9622
|
+
for (const name of clearedSessionCookieNames(environmentRef, present)) {
|
|
9617
9623
|
removeCookie(store, name);
|
|
9618
9624
|
}
|
|
9619
9625
|
}
|
|
@@ -9624,7 +9630,7 @@ async function pbServer(opts) {
|
|
|
9624
9630
|
"import the generated palbe.gen.ts once in app/layout.tsx \u2014 the root-layout import configures Server Components and Route Handlers too."
|
|
9625
9631
|
);
|
|
9626
9632
|
const store = opts?.cookies ?? await nextCookieStore();
|
|
9627
|
-
const ref =
|
|
9633
|
+
const ref = config.environmentRef;
|
|
9628
9634
|
const rt = buildRuntime({ ...config, storage: serverCookieAdapter(store, ref) });
|
|
9629
9635
|
return createBoundClient(rt);
|
|
9630
9636
|
}
|
|
@@ -9635,7 +9641,7 @@ async function pbServer(opts) {
|
|
|
9635
9641
|
decodeSessionCookies,
|
|
9636
9642
|
encodeSessionCookies,
|
|
9637
9643
|
encodeSessionCookiesDecoded,
|
|
9638
|
-
|
|
9644
|
+
environmentRefFromApiKey,
|
|
9639
9645
|
handleAuthCallback,
|
|
9640
9646
|
palbeMiddleware,
|
|
9641
9647
|
pbServer,
|