@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.
Files changed (47) hide show
  1. package/README.md +11 -9
  2. package/dist/{analytics-facade-ChlBRcLZ.d.cts → analytics-facade-BOxQ8IP2.d.cts} +8 -16
  3. package/dist/{analytics-facade-G0il4NrT.d.ts → analytics-facade-yfMJ69vw.d.ts} +8 -16
  4. package/dist/{chunk-AIPUO4QX.js → chunk-3HVTEZ7N.js} +30 -36
  5. package/dist/chunk-3HVTEZ7N.js.map +1 -0
  6. package/dist/{chunk-VJXFABBW.js → chunk-6VGKMNXO.js} +11 -11
  7. package/dist/chunk-6VGKMNXO.js.map +1 -0
  8. package/dist/chunk-S7NAY3MW.js +24 -0
  9. package/dist/chunk-S7NAY3MW.js.map +1 -0
  10. package/dist/gen/cli.cjs +32 -6
  11. package/dist/gen/cli.cjs.map +1 -1
  12. package/dist/gen/cli.js +28 -7
  13. package/dist/gen/cli.js.map +1 -1
  14. package/dist/index.cjs +3 -10
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +3 -3
  17. package/dist/index.d.ts +3 -3
  18. package/dist/index.js +2 -2
  19. package/dist/internal.cjs +33 -32
  20. package/dist/internal.cjs.map +1 -1
  21. package/dist/internal.d.cts +3 -3
  22. package/dist/internal.d.ts +3 -3
  23. package/dist/internal.js +2 -2
  24. package/dist/next/client.cjs +50 -46
  25. package/dist/next/client.cjs.map +1 -1
  26. package/dist/next/client.d.cts +1 -1
  27. package/dist/next/client.d.ts +1 -1
  28. package/dist/next/client.js +12 -10
  29. package/dist/next/client.js.map +1 -1
  30. package/dist/next/index.cjs +53 -47
  31. package/dist/next/index.cjs.map +1 -1
  32. package/dist/next/index.d.cts +10 -10
  33. package/dist/next/index.d.ts +10 -10
  34. package/dist/next/index.js +14 -13
  35. package/dist/next/index.js.map +1 -1
  36. package/dist/{pb-B_6o5p79.d.cts → pb-B3h3NIPE.d.cts} +1 -1
  37. package/dist/{pb-nPBhqhJr.d.ts → pb-QRISxPd1.d.ts} +1 -1
  38. package/dist/react/index.cjs +1 -1
  39. package/dist/react/index.cjs.map +1 -1
  40. package/dist/react/index.d.cts +1 -1
  41. package/dist/react/index.d.ts +1 -1
  42. package/dist/react/index.js +2 -2
  43. package/package.json +2 -2
  44. package/dist/chunk-AIPUO4QX.js.map +0 -1
  45. package/dist/chunk-PZ5AY32C.js +0 -10
  46. package/dist/chunk-PZ5AY32C.js.map +0 -1
  47. package/dist/chunk-VJXFABBW.js.map +0 -1
package/README.md CHANGED
@@ -29,18 +29,20 @@ Then link your project and generate the typed client:
29
29
  npx palbase web link
30
30
  ```
31
31
 
32
- `palbase web link` writes `palbe.gen.ts` (the typed client config + namespaces),
33
- wires `import './palbe.gen';` into your app entry, and adds a `predev`/`prebuild`
34
- hook that keeps the types in sync. **Commit `palbe.gen.ts`** it's the typed
35
- client your app imports, not a build artifact.
36
-
37
- The generated file calls `__configure(...)` with your project's URL, app ID, and
38
- anon API key at module load, so importing it once at startup is all the setup
39
- there is.
32
+ `palbase web link` writes the committed generator inputs
33
+ `Palbase/openapi.json` and `Palbase/palbase-config.json`, runs `palbe-gen` when
34
+ `@palbase/web` is installed, wires `import './palbe.gen';` into your app entry,
35
+ and adds a `predev`/`prebuild` hook that keeps the typed client in sync. Commit
36
+ the `Palbase/` inputs and `palbe.gen.ts`; the generated client is source your app
37
+ imports, not a build artifact.
38
+
39
+ The generated file calls `__configure(...)` with the linked Environment ref,
40
+ URL, app ID, and publishable API key at module load, so importing it once at
41
+ startup is all the setup there is.
40
42
  If you forget to import it, every `pb` call throws a guided `BackendError`
41
43
  (`kind: 'notConfigured'`).
42
44
 
43
- > Regenerate any time your backend changes: `npx palbase types` (or just run
45
+ > Regenerate any time your backend changes: `npx palbe-gen` (or just run
44
46
  > `dev`/`build` — the hook does it for you).
45
47
 
46
48
  ---
@@ -79,8 +79,7 @@ declare class HttpClient$1 {
79
79
  * with the parent at runtime — later changes on the parent propagate to
80
80
  * the scope and vice versa.
81
81
  *
82
- * Typical use: tagging admin calls with `x-palbase-project: <ref>` so the
83
- * gateway can route them to the correct project's data plane.
82
+ * Typical use: adding an Environment-routing header for an admin call.
84
83
  */
85
84
  withHeaders(extra: Record<string, string>): HttpClient$1;
86
85
  /** Add a request interceptor. Runs before every request. */
@@ -169,8 +168,7 @@ declare class HttpClient {
169
168
  * with the parent at runtime — later changes on the parent propagate to
170
169
  * the scope and vice versa.
171
170
  *
172
- * Typical use: tagging admin calls with `x-palbase-project: <ref>` so the
173
- * gateway can route them to the correct project's data plane.
171
+ * Typical use: adding an Environment-routing header for an admin call.
174
172
  */
175
173
  withHeaders(extra: Record<string, string>): HttpClient;
176
174
  /** Add a request interceptor. Runs before every request. */
@@ -622,19 +620,13 @@ interface PalbeConfig {
622
620
  apiKey: string;
623
621
  /** Registered app identity persisted by `palbase web link`. */
624
622
  appId: string;
623
+ /** Stable reference of the linked Palbase Environment. */
624
+ environmentRef: string;
625
+ oauth?: PalbeOAuthConfig;
625
626
  /**
626
- * The ENVIRONMENT this config targets — informational only.
627
- *
628
- * `url` and `apiKey` ALREADY identify the environment (the ref is the host
629
- * label and is embedded in the key), so nothing at runtime reads this: it is
630
- * here so a developer looking at the generated file can see WHICH runtime it
631
- * points at. It replaces the old `branch` field — the Palbase branch is gone
632
- * as a resource, and a second, drift-prone name for the same runtime is
633
- * exactly how a build ends up talking to production from a staging checkout.
627
+ * Refresh-token persistence. Default: environment-scoped localStorage in
628
+ * browsers, memory elsewhere.
634
629
  */
635
- environmentRef?: string;
636
- oauth?: PalbeOAuthConfig;
637
- /** Refresh-token persistence. Default: endpoint-scoped localStorage in browsers, memory elsewhere. */
638
630
  storage?: SessionStorageAdapter;
639
631
  /** Extra headers on every request. */
640
632
  headers?: Record<string, string>;
@@ -654,7 +646,7 @@ type FlagsView = Readonly<Record<string, F>>;
654
646
  * one-shot snapshot fetches with zero timers and zero storage access, so a
655
647
  * pbServer request that reads flags pays exactly one HTTP call.
656
648
  *
657
- * localStorage persistence is scoped per endpoint ref (`palbe.flags.<ref>`),
649
+ * localStorage persistence is scoped per environment ref (`palbe.flags.<ref>`),
658
650
  * mirroring the session-storage key convention.
659
651
  */
660
652
  declare class PalbeFlags {
@@ -79,8 +79,7 @@ declare class HttpClient$1 {
79
79
  * with the parent at runtime — later changes on the parent propagate to
80
80
  * the scope and vice versa.
81
81
  *
82
- * Typical use: tagging admin calls with `x-palbase-project: <ref>` so the
83
- * gateway can route them to the correct project's data plane.
82
+ * Typical use: adding an Environment-routing header for an admin call.
84
83
  */
85
84
  withHeaders(extra: Record<string, string>): HttpClient$1;
86
85
  /** Add a request interceptor. Runs before every request. */
@@ -169,8 +168,7 @@ declare class HttpClient {
169
168
  * with the parent at runtime — later changes on the parent propagate to
170
169
  * the scope and vice versa.
171
170
  *
172
- * Typical use: tagging admin calls with `x-palbase-project: <ref>` so the
173
- * gateway can route them to the correct project's data plane.
171
+ * Typical use: adding an Environment-routing header for an admin call.
174
172
  */
175
173
  withHeaders(extra: Record<string, string>): HttpClient;
176
174
  /** Add a request interceptor. Runs before every request. */
@@ -622,19 +620,13 @@ interface PalbeConfig {
622
620
  apiKey: string;
623
621
  /** Registered app identity persisted by `palbase web link`. */
624
622
  appId: string;
623
+ /** Stable reference of the linked Palbase Environment. */
624
+ environmentRef: string;
625
+ oauth?: PalbeOAuthConfig;
625
626
  /**
626
- * The ENVIRONMENT this config targets — informational only.
627
- *
628
- * `url` and `apiKey` ALREADY identify the environment (the ref is the host
629
- * label and is embedded in the key), so nothing at runtime reads this: it is
630
- * here so a developer looking at the generated file can see WHICH runtime it
631
- * points at. It replaces the old `branch` field — the Palbase branch is gone
632
- * as a resource, and a second, drift-prone name for the same runtime is
633
- * exactly how a build ends up talking to production from a staging checkout.
627
+ * Refresh-token persistence. Default: environment-scoped localStorage in
628
+ * browsers, memory elsewhere.
634
629
  */
635
- environmentRef?: string;
636
- oauth?: PalbeOAuthConfig;
637
- /** Refresh-token persistence. Default: endpoint-scoped localStorage in browsers, memory elsewhere. */
638
630
  storage?: SessionStorageAdapter;
639
631
  /** Extra headers on every request. */
640
632
  headers?: Record<string, string>;
@@ -654,7 +646,7 @@ type FlagsView = Readonly<Record<string, F>>;
654
646
  * one-shot snapshot fetches with zero timers and zero storage access, so a
655
647
  * pbServer request that reads flags pays exactly one HTTP call.
656
648
  *
657
- * localStorage persistence is scoped per endpoint ref (`palbe.flags.<ref>`),
649
+ * localStorage persistence is scoped per environment ref (`palbe.flags.<ref>`),
658
650
  * mirroring the session-storage key convention.
659
651
  */
660
652
  declare class PalbeFlags {
@@ -1,6 +1,7 @@
1
1
  import {
2
- __export
3
- } from "./chunk-PZ5AY32C.js";
2
+ __export,
3
+ environmentRefFromPublishableApiKey
4
+ } from "./chunk-S7NAY3MW.js";
4
5
 
5
6
  // ../core/dist/index.js
6
7
  var CACHE_TTL_MS = 5 * 60 * 1e3;
@@ -17,18 +18,9 @@ var PalbaseError = class extends Error {
17
18
  }
18
19
  };
19
20
  var PALBASE_DEFAULT_HOST = "api.palbase.studio";
20
- var REF_LEN = 8;
21
- var BASE62_RE = /^[0-9A-Za-z]+$/;
22
- function parseProjectRef(apiKey) {
23
- if (apiKey.length < 13) return null;
24
- if (!apiKey.startsWith("pb_")) return null;
25
- if (apiKey[11] !== "_") return null;
26
- const ref = apiKey.slice(3, 11);
27
- if (ref.length !== REF_LEN) return null;
28
- if (!BASE62_RE.test(ref)) return null;
29
- const scope = apiKey[12];
30
- if (scope !== "c") return null;
31
- return ref;
21
+ var API_KEY_RE = /^pb_([a-z0-9]+)_c[A-Za-z0-9]{20}$/;
22
+ function parseEnvironmentRef(apiKey) {
23
+ return API_KEY_RE.exec(apiKey)?.[1] ?? null;
32
24
  }
33
25
  var MAX_RETRIES = 3;
34
26
  var INITIAL_BACKOFF_MS = 200;
@@ -58,8 +50,7 @@ var HttpClient = class _HttpClient {
58
50
  * with the parent at runtime — later changes on the parent propagate to
59
51
  * the scope and vice versa.
60
52
  *
61
- * Typical use: tagging admin calls with `x-palbase-project: <ref>` so the
62
- * gateway can route them to the correct project's data plane.
53
+ * Typical use: adding an Environment-routing header for an admin call.
63
54
  */
64
55
  withHeaders(extra) {
65
56
  const mergedHeaders = { ...this.options?.headers ?? {}, ...extra };
@@ -100,10 +91,10 @@ var HttpClient = class _HttpClient {
100
91
  if (this.options?.url) {
101
92
  return this.options.url;
102
93
  }
103
- if (this.apiKey && parseProjectRef(this.apiKey) === null) {
94
+ if (this.apiKey && parseEnvironmentRef(this.apiKey) === null) {
104
95
  throw new PalbaseError(
105
96
  "invalid_api_key",
106
- 'Invalid API key format. Expected pb_{ref}_{scope}{random}. For dev/staging pass `url: "https://api.dev.palbase.studio"` via options.',
97
+ 'Invalid API key format. Expected pb_{environment_ref}_c{20_base62_chars}. For dev/staging pass `url: "https://api.dev.palbase.studio"` via options.',
107
98
  0
108
99
  );
109
100
  }
@@ -116,10 +107,6 @@ var HttpClient = class _HttpClient {
116
107
  const effectiveKey = this.apiKey;
117
108
  if (effectiveKey) {
118
109
  headers["apikey"] = effectiveKey;
119
- const ref = parseProjectRef(effectiveKey);
120
- if (ref) {
121
- headers["X-Project-Ref"] = ref;
122
- }
123
110
  }
124
111
  const token = this.tokenManager?.getAccessToken();
125
112
  if (token) {
@@ -1125,13 +1112,6 @@ var AuthClient = class {
1125
1112
  }
1126
1113
  };
1127
1114
 
1128
- // src/api-key.ts
1129
- var API_KEY_RE = /^pb_([^_]+)_[cs][A-Za-z0-9]{20}$/;
1130
- function endpointRefFromApiKey(apiKey) {
1131
- const m = API_KEY_RE.exec(apiKey);
1132
- return m ? m[1] ?? "" : "";
1133
- }
1134
-
1135
1115
  // src/analytics-facade.ts
1136
1116
  var EVENT_NAME_RE = /^[a-zA-Z$][a-zA-Z0-9_.:$-]{0,63}$/;
1137
1117
  var FLUSH_AT = 20;
@@ -1189,7 +1169,7 @@ var AnalyticsState = class {
1189
1169
  idKey;
1190
1170
  optOutKey;
1191
1171
  constructor(rt) {
1192
- const ref = endpointRefFromApiKey(rt.config.apiKey);
1172
+ const ref = rt.config.environmentRef;
1193
1173
  this.idKey = ref ? `palbe.analytics.id.${ref}` : "palbe.analytics.id";
1194
1174
  this.optOutKey = ref ? `palbe.analytics.optout.${ref}` : "palbe.analytics.optout";
1195
1175
  rt.auth.onAuthEvent((event) => {
@@ -2548,7 +2528,7 @@ var PalbeFlags = class {
2548
2528
  constructor(rt) {
2549
2529
  this.transport = new FlagsClient(rt.http);
2550
2530
  const browser = typeof document !== "undefined";
2551
- const ref = endpointRefFromApiKey(rt.config.apiKey);
2531
+ const ref = rt.config.environmentRef;
2552
2532
  const options = {
2553
2533
  auth: palbeAuthAdapter(rt.auth),
2554
2534
  ...ref ? { storageKey: `palbe.flags.${ref}` } : {},
@@ -8287,7 +8267,7 @@ var AnonTokenProvider = class {
8287
8267
  }
8288
8268
  /**
8289
8269
  * Raw fetch, deliberately NOT through HttpClient/palbeRequest: the mint
8290
- * must carry the project apikey and NEVER a Bearer (iOS keeps
8270
+ * must carry the Environment API key and NEVER a Bearer (iOS keeps
8291
8271
  * `/auth/anonymous` on the unauthenticated-path list), and HttpClient's
8292
8272
  * pre-flight would try to refresh a stale session before an anon mint —
8293
8273
  * exactly the entanglement this provider exists to avoid.
@@ -8944,10 +8924,25 @@ function defaultSessionStorage(key) {
8944
8924
  }
8945
8925
 
8946
8926
  // src/version.ts
8947
- var VERSION = "2.0.1";
8927
+ var VERSION = "3.0.0";
8948
8928
 
8949
8929
  // src/runtime.ts
8950
8930
  function buildRuntime(config) {
8931
+ const keyEnvironmentRef = environmentRefFromPublishableApiKey(config.apiKey);
8932
+ if (keyEnvironmentRef === "") {
8933
+ throw new Error("PalbeConfig.apiKey does not contain a valid publishable Environment identity");
8934
+ } else if (config.environmentRef !== keyEnvironmentRef) {
8935
+ throw new Error("PalbeConfig.environmentRef must match the Environment identity in apiKey");
8936
+ }
8937
+ let runtimeURL;
8938
+ try {
8939
+ runtimeURL = new URL(config.url);
8940
+ } catch {
8941
+ throw new Error("PalbeConfig.url must be a valid URL");
8942
+ }
8943
+ if (runtimeURL.hostname.endsWith(".palbase.studio") && runtimeURL.hostname.split(".")[0] !== config.environmentRef) {
8944
+ throw new Error("PalbeConfig.url must match environmentRef for palbase.studio");
8945
+ }
8951
8946
  const http = new HttpClient(config.apiKey, {
8952
8947
  url: config.url,
8953
8948
  headers: { "X-Client-Info": `palbe-web/${VERSION}`, ...config.headers }
@@ -8956,7 +8951,7 @@ function buildRuntime(config) {
8956
8951
  const tokenManager = new TokenManager();
8957
8952
  http.tokenManager = tokenManager;
8958
8953
  const authClient = new AuthClient(http, tokenManager);
8959
- const ref = endpointRefFromApiKey(config.apiKey);
8954
+ const ref = config.environmentRef;
8960
8955
  const storage = config.storage ?? defaultSessionStorage(ref ? `palbe.session.${ref}` : void 0);
8961
8956
  const persisted = storage.load();
8962
8957
  if (persisted) {
@@ -9333,7 +9328,6 @@ function __reset() {
9333
9328
  }
9334
9329
 
9335
9330
  export {
9336
- endpointRefFromApiKey,
9337
9331
  BackendError,
9338
9332
  isBackendError,
9339
9333
  PalbeAnalytics,
@@ -9357,4 +9351,4 @@ export {
9357
9351
  pb,
9358
9352
  createBoundClient
9359
9353
  };
9360
- //# sourceMappingURL=chunk-AIPUO4QX.js.map
9354
+ //# sourceMappingURL=chunk-3HVTEZ7N.js.map