@stackable-labs/embeddables 2.21.1 → 2.23.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 CHANGED
@@ -58,13 +58,29 @@ import '@stackable-labs/embeddables/styles';
58
58
 
59
59
  ## Dev Overrides
60
60
 
61
- For local development against a deployed host app, the SDK supports runtime `bundleUrl` overrides via query parameter. Append to your host app URL:
61
+ For local development against a deployed host app, the SDK supports runtime `bundleUrl` overrides via the `_stackable_dev` (and `_stackable_staging`) query parameter. Append to your host app URL:
62
+
63
+ **Blob format (default — emitted by the CLI when authenticated):** the value after the colon is a `base64url`-encoded JSON `{url, token}` blob; the token is short-lived and verified by the host.
64
+
65
+ ```
66
+ ?_stackable_dev=ext-123:eyJ1cmwiOiJodHRwczovL2FiYy50cnljbG91ZGZsYXJlLmNvbSIsInRva2VuIjoiZXlKaGJHY2lPaUpJVXp...
67
+ ```
68
+
69
+ **Legacy format (fallback — no token):**
70
+
71
+ ```
72
+ ?_stackable_dev=ext-123:https://abc.trycloudflare.com
73
+ ```
74
+
75
+ `_stackable_staging` uses the same blob format and **always requires the token** (no legacy fallback).
76
+
77
+ For multiple extensions, comma-join entries in a single param (mixed blob + legacy is fine — the parser tries each entry independently):
62
78
 
63
79
  ```
64
- ?_stackable_dev=ext-123%3Ahttps%3A%2F%2Fabc.trycloudflare.com
80
+ ?_stackable_dev=ext-123:eyJ1cmwi...,ext-456:eyJ1cmwi...
65
81
  ```
66
82
 
67
- `ExtensionSetup` automatically detects the `_stackable_dev` param, validates the URL against a domain allowlist (localhost, trycloudflare.com, ngrok-free.app), and swaps the `bundleUrl` for matching extensions. A floating "🔧 Dev Mode" badge appears when overrides are active, with a "Clear" button to remove them.
83
+ `ExtensionSetup` automatically detects both params, validates the URL against a domain allowlist (localhost, trycloudflare.com, ngrok-free.app), verifies the token when present, and swaps the `bundleUrl` for matching extensions. A floating "🔧 Dev Mode" badge appears when overrides are active, with a "Clear" button to remove them.
68
84
 
69
85
  No host app code changes required — this is built into `ExtensionSetup`.
70
86
 
@@ -14,9 +14,10 @@ interface WidgetAppProps {
14
14
  colors?: WidgetColors;
15
15
  instanceId: string;
16
16
  customerId?: string;
17
- customerEmail?: string;
18
17
  customerName?: string;
18
+ customerEmail?: string;
19
+ customerProvider?: string;
19
20
  snippetKey: string;
20
21
  }
21
- export declare const WidgetApp: ({ queryApiBase, apiBase, appId, theme, icon, iconUrl, position, offsetX, offsetY, colors, instanceId, customerId, customerEmail, customerName, snippetKey, }: WidgetAppProps) => import("react/jsx-runtime").JSX.Element;
22
+ export declare const WidgetApp: ({ queryApiBase, apiBase, appId, theme, icon, iconUrl, position, offsetX, offsetY, colors, snippetKey, instanceId, customerId, customerName, customerEmail, customerProvider, }: WidgetAppProps) => import("react/jsx-runtime").JSX.Element;
22
23
  export {};
@@ -12,8 +12,9 @@ export interface ExtensionSetupProps {
12
12
  appId?: string;
13
13
  instanceId?: string;
14
14
  customerId?: string;
15
- customerEmail?: string;
16
15
  customerName?: string;
16
+ customerEmail?: string;
17
+ customerProvider?: string;
17
18
  children: React.ReactNode;
18
19
  }
19
- export declare const ExtensionSetup: ({ instanceId, queryApiBase, apiBase, appId, children, customerId, customerEmail, customerName, }: ExtensionSetupProps) => import("react/jsx-runtime").JSX.Element | null;
20
+ export declare const ExtensionSetup: ({ instanceId, queryApiBase, apiBase, appId, children, customerId, customerName, customerEmail, customerProvider, }: ExtensionSetupProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Host-side identity-claim filtering.
3
+ *
4
+ * When an extension's useExtendIdentity handler returns claims, the host
5
+ * filters the result per-extension against `manifest.identityClaims` before
6
+ * merging into `identityState.user.metadata` and forwarding to the JWT
7
+ * signing endpoint as `custom_claims`.
8
+ *
9
+ * Standard JWT claims (external_id, email, name) are exempt — they're part
10
+ * of the documented signing contract and may be overridden by any extension
11
+ * with `identity:extend` permission without explicit declaration.
12
+ *
13
+ * Undeclared custom keys are dropped with a console.warn so extension authors
14
+ * see the signal during local development and Studio preview.
15
+ */
16
+ import { STANDARD_IDENTITY_CLAIM_KEYS } from '@stackable-labs/sdk-extension-contracts';
17
+ /** Re-export so existing test imports from this module keep working. */
18
+ export { STANDARD_IDENTITY_CLAIM_KEYS };
19
+ /**
20
+ * Filter raw claims returned from a useExtendIdentity handler against the
21
+ * extension's manifest.identityClaims declaration.
22
+ *
23
+ * - Standard JWT claims (external_id, email, name) always allowed
24
+ * - Custom keys must be in `declared`
25
+ * - Undeclared keys dropped with a console.warn referencing the extension id
26
+ */
27
+ export declare const filterByDeclaration: (raw: Record<string, unknown>, declared: Set<string>, extensionId: string) => Record<string, unknown>;