powr-sdk-web 6.2.1 → 6.4.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/dist/index.js CHANGED
@@ -76,6 +76,12 @@ Object.defineProperty(exports, "POWR_DENSITIES", {
76
76
  return _theme.POWR_DENSITIES;
77
77
  }
78
78
  });
79
+ Object.defineProperty(exports, "POWR_IMPERSONATOR_KEY", {
80
+ enumerable: true,
81
+ get: function get() {
82
+ return _impersonate.POWR_IMPERSONATOR_KEY;
83
+ }
84
+ });
79
85
  Object.defineProperty(exports, "POWR_SCHEMES", {
80
86
  enumerable: true,
81
87
  get: function get() {
@@ -220,6 +226,12 @@ Object.defineProperty(exports, "PowrBaseTools", {
220
226
  return _tools["default"];
221
227
  }
222
228
  });
229
+ Object.defineProperty(exports, "PowrBaseTracker", {
230
+ enumerable: true,
231
+ get: function get() {
232
+ return _track.PowrBaseTracker;
233
+ }
234
+ });
223
235
  Object.defineProperty(exports, "PowrBaseUploader", {
224
236
  enumerable: true,
225
237
  get: function get() {
@@ -244,6 +256,18 @@ Object.defineProperty(exports, "PowrCalendarStrip", {
244
256
  return _calendar["default"];
245
257
  }
246
258
  });
259
+ Object.defineProperty(exports, "PowrImpersonationBar", {
260
+ enumerable: true,
261
+ get: function get() {
262
+ return _impersonate.PowrImpersonationBar;
263
+ }
264
+ });
265
+ Object.defineProperty(exports, "PowrLoginAsDialog", {
266
+ enumerable: true,
267
+ get: function get() {
268
+ return _impersonate.PowrLoginAsDialog;
269
+ }
270
+ });
247
271
  Object.defineProperty(exports, "PowrOnboardingProvider", {
248
272
  enumerable: true,
249
273
  get: function get() {
@@ -304,6 +328,18 @@ Object.defineProperty(exports, "buildPowrSsoUrl", {
304
328
  return _sso.buildPowrSsoUrl;
305
329
  }
306
330
  });
331
+ Object.defineProperty(exports, "canStartLoginAs", {
332
+ enumerable: true,
333
+ get: function get() {
334
+ return _impersonate.canStartLoginAs;
335
+ }
336
+ });
337
+ Object.defineProperty(exports, "clearImpersonator", {
338
+ enumerable: true,
339
+ get: function get() {
340
+ return _impersonate.clearImpersonator;
341
+ }
342
+ });
307
343
  Object.defineProperty(exports, "clearStoredSession", {
308
344
  enumerable: true,
309
345
  get: function get() {
@@ -328,12 +364,24 @@ Object.defineProperty(exports, "defineOptionalAppStep", {
328
364
  return _onboarding.defineOptionalAppStep;
329
365
  }
330
366
  });
367
+ Object.defineProperty(exports, "enterLoginAs", {
368
+ enumerable: true,
369
+ get: function get() {
370
+ return _impersonate.enterLoginAs;
371
+ }
372
+ });
331
373
  Object.defineProperty(exports, "evaluateSteps", {
332
374
  enumerable: true,
333
375
  get: function get() {
334
376
  return _onboarding.evaluateSteps;
335
377
  }
336
378
  });
379
+ Object.defineProperty(exports, "exitLoginAs", {
380
+ enumerable: true,
381
+ get: function get() {
382
+ return _impersonate.exitLoginAs;
383
+ }
384
+ });
337
385
  Object.defineProperty(exports, "fetchThemePreference", {
338
386
  enumerable: true,
339
387
  get: function get() {
@@ -496,6 +544,12 @@ Object.defineProperty(exports, "profileNameStep", {
496
544
  return _onboarding.profileNameStep;
497
545
  }
498
546
  });
547
+ Object.defineProperty(exports, "readImpersonator", {
548
+ enumerable: true,
549
+ get: function get() {
550
+ return _impersonate.readImpersonator;
551
+ }
552
+ });
499
553
  Object.defineProperty(exports, "readStoredSession", {
500
554
  enumerable: true,
501
555
  get: function get() {
@@ -556,6 +610,12 @@ Object.defineProperty(exports, "usePowrThemeHost", {
556
610
  return _theme.usePowrThemeHost;
557
611
  }
558
612
  });
613
+ Object.defineProperty(exports, "viewAsLabel", {
614
+ enumerable: true,
615
+ get: function get() {
616
+ return _impersonate.viewAsLabel;
617
+ }
618
+ });
559
619
  Object.defineProperty(exports, "writeStoredSession", {
560
620
  enumerable: true,
561
621
  get: function get() {
@@ -591,5 +651,7 @@ var _sessionMessages = require("./utils/sessionMessages");
591
651
  var _theme = require("./theme");
592
652
  var _session = require("./session");
593
653
  var _shell = require("./shell");
654
+ var _impersonate = require("./impersonate");
655
+ var _track = require("./track");
594
656
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
595
657
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
@@ -16,6 +16,7 @@ exports.usePowrSession = usePowrSession;
16
16
  exports.writeStoredSession = writeStoredSession;
17
17
  var _react = _interopRequireWildcard(require("react"));
18
18
  var _jwt = require("../utils/jwt");
19
+ var _storage = require("../impersonate/storage");
19
20
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
20
21
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
21
22
  function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
@@ -29,16 +30,16 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
29
30
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
30
31
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
31
32
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
32
- /**
33
- * Powr session — the file every new app used to copy (`utils/store.ts`).
34
- *
35
- * Owns `localStorage['auth-store']` in the zustand-persist shape
36
- * `{ state: { user, token }, version }` so:
37
- * - `apiCall` (utils/auth.getAuthToken) keeps reading the bearer from it
38
- * - apps that already run a zustand `auth-store` can pass `user`/`token`
39
- * as props (controlled) and nothing moves.
40
- *
41
- * No zustand dependency. Plain React context.
33
+ /**
34
+ * Powr session — the file every new app used to copy (`utils/store.ts`).
35
+ *
36
+ * Owns `localStorage['auth-store']` in the zustand-persist shape
37
+ * `{ state: { user, token }, version }` so:
38
+ * - `apiCall` (utils/auth.getAuthToken) keeps reading the bearer from it
39
+ * - apps that already run a zustand `auth-store` can pass `user`/`token`
40
+ * as props (controlled) and nothing moves.
41
+ *
42
+ * No zustand dependency. Plain React context.
42
43
  */
43
44
 
44
45
  var POWR_SESSION_STORAGE_KEY = exports.POWR_SESSION_STORAGE_KEY = "auth-store";
@@ -111,14 +112,14 @@ var PowrSessionContext = /*#__PURE__*/(0, _react.createContext)(_objectSpread(_o
111
112
  clear: function clear() {}
112
113
  }));
113
114
 
114
- /**
115
- * @param {object} props
116
- * @param {object|null} [props.user] - Controlled mode: app's own store is truth.
117
- * @param {string|null} [props.token] - Controlled mode.
118
- * @param {string|null} [props.refreshToken]
119
- * @param {(session: {user, token, refreshToken}) => void} [props.onChange] - After setSession / clear.
120
- * @param {() => void} [props.onLogout] - Controlled mode: clear your store here.
121
- * @param {boolean} [props.persist=true] - Uncontrolled mode: write `auth-store`.
115
+ /**
116
+ * @param {object} props
117
+ * @param {object|null} [props.user] - Controlled mode: app's own store is truth.
118
+ * @param {string|null} [props.token] - Controlled mode.
119
+ * @param {string|null} [props.refreshToken]
120
+ * @param {(session: {user, token, refreshToken}) => void} [props.onChange] - After setSession / clear.
121
+ * @param {() => void} [props.onLogout] - Controlled mode: clear your store here.
122
+ * @param {boolean} [props.persist=true] - Uncontrolled mode: write `auth-store`.
122
123
  */
123
124
  function PowrSessionProvider(_ref2) {
124
125
  var userProp = _ref2.user,
@@ -183,6 +184,7 @@ function PowrSessionProvider(_ref2) {
183
184
  }, [controlled, persist]);
184
185
  var clear = (0, _react.useCallback)(function () {
185
186
  var _onChangeRef$current2;
187
+ (0, _storage.clearImpersonator)();
186
188
  if (!controlled) {
187
189
  setLocal(EMPTY);
188
190
  clearStoredSession();
@@ -16,6 +16,7 @@ var _PowrOnboardingProvider = _interopRequireDefault(require("../onboarding/Powr
16
16
  var _useMediaQuery = _interopRequireDefault(require("../utils/useMediaQuery"));
17
17
  var _styles = require("./styles");
18
18
  var _parts = require("./parts");
19
+ var _impersonate = require("../impersonate");
19
20
  var _excluded = ["theme", "presets", "scheme", "density", "preset", "persistTheme", "user", "token", "refreshToken", "onSessionChange", "onLogout"];
20
21
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
21
22
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
@@ -36,16 +37,16 @@ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t =
36
37
  var config = require("../config");
37
38
  var POWR_SHELL_MODES = exports.POWR_SHELL_MODES = Object.freeze(["sidebar", "topbar"]);
38
39
 
39
- /**
40
- * PowrBaseAppWrapper — the one root mount for a Powr web app.
41
- *
42
- * Replaces the files every new app copied: auth store, route guards, top bar /
43
- * sidebar, login page glue, providers. Chrome + selectors live here; palette,
44
- * presets, logo, nav items, product roles and public pages stay in the product.
45
- *
46
- * Guardrails: no colours of its own (every colour is `var(--powr-*)`), more
47
- * than one shape (`sidebar` | `topbar`), no `next/*` import — `Link` and
48
- * `pathname` come in as props, like `apiUrl` does elsewhere.
40
+ /**
41
+ * PowrBaseAppWrapper — the one root mount for a Powr web app.
42
+ *
43
+ * Replaces the files every new app copied: auth store, route guards, top bar /
44
+ * sidebar, login page glue, providers. Chrome + selectors live here; palette,
45
+ * presets, logo, nav items, product roles and public pages stay in the product.
46
+ *
47
+ * Guardrails: no colours of its own (every colour is `var(--powr-*)`), more
48
+ * than one shape (`sidebar` | `topbar`), no `next/*` import — `Link` and
49
+ * `pathname` come in as props, like `apiUrl` does elsewhere.
49
50
  */
50
51
  function PowrBaseAppWrapper(props) {
51
52
  var theme = props.theme,
@@ -82,6 +83,7 @@ function PowrBaseAppWrapper(props) {
82
83
  }, shell);
83
84
  }
84
85
  function Shell(_ref) {
86
+ var _readImpersonator;
85
87
  var _ref$mode = _ref.mode,
86
88
  mode = _ref$mode === void 0 ? "topbar" : _ref$mode,
87
89
  _ref$brand = _ref.brand,
@@ -136,6 +138,20 @@ function Shell(_ref) {
136
138
  _useState4 = _slicedToArray(_useState3, 2),
137
139
  settingsOpen = _useState4[0],
138
140
  setSettingsOpen = _useState4[1];
141
+ var _useState5 = (0, _react.useState)(false),
142
+ _useState6 = _slicedToArray(_useState5, 2),
143
+ loginAsOpen = _useState6[0],
144
+ setLoginAsOpen = _useState6[1];
145
+ var viewingAs = Boolean(((_readImpersonator = (0, _impersonate.readImpersonator)()) === null || _readImpersonator === void 0 ? void 0 : _readImpersonator.token) && session.token);
146
+ var chromeOffset = _styles.HEADER_HEIGHT + (viewingAs ? 36 : 0);
147
+ var leaveAndSignOut = (0, _react.useCallback)(function () {
148
+ var pending = (0, _impersonate.notifyImpersonationExit)({
149
+ apiUrl: apiUrl,
150
+ projectId: projectId
151
+ });
152
+ session.clear();
153
+ pending["catch"](function () {});
154
+ }, [apiUrl, projectId, session]);
139
155
  var closeNav = (0, _react.useCallback)(function () {
140
156
  return setNavOpen(false);
141
157
  }, []);
@@ -214,8 +230,20 @@ function Shell(_ref) {
214
230
  var showBurger = narrow && nav.length > 0;
215
231
  var content = /*#__PURE__*/_react["default"].createElement("div", {
216
232
  style: _styles.s.root
217
- }, /*#__PURE__*/_react["default"].createElement("header", {
218
- style: _styles.s.header
233
+ }, /*#__PURE__*/_react["default"].createElement("div", {
234
+ style: {
235
+ position: "sticky",
236
+ top: 0,
237
+ zIndex: 40
238
+ }
239
+ }, /*#__PURE__*/_react["default"].createElement(_impersonate.PowrImpersonationBar, {
240
+ apiUrl: apiUrl,
241
+ projectId: projectId
242
+ }), /*#__PURE__*/_react["default"].createElement("header", {
243
+ style: _objectSpread(_objectSpread({}, _styles.s.header), {}, {
244
+ position: "relative",
245
+ top: "auto"
246
+ })
219
247
  }, showBurger ? /*#__PURE__*/_react["default"].createElement("button", {
220
248
  type: "button",
221
249
  "aria-label": "Menu",
@@ -247,16 +275,22 @@ function Shell(_ref) {
247
275
  onOpenSettings: showThemeSettings ? function () {
248
276
  return setSettingsOpen(true);
249
277
  } : null,
250
- onLogout: session.clear
278
+ onLoginAs: (0, _impersonate.canStartLoginAs)(session) ? function () {
279
+ return setLoginAsOpen(true);
280
+ } : null,
281
+ onLogout: leaveAndSignOut
251
282
  }) : /*#__PURE__*/_react["default"].createElement(Link, {
252
283
  href: loginHref,
253
284
  style: _objectSpread(_objectSpread({}, _styles.s.navItem(false, false)), {}, {
254
285
  border: "1px solid ".concat(_styles.v.border)
255
286
  })
256
- }, "Sign in"))), /*#__PURE__*/_react["default"].createElement("div", {
287
+ }, "Sign in")))), /*#__PURE__*/_react["default"].createElement("div", {
257
288
  style: _styles.s.body
258
289
  }, vertical && nav.length ? /*#__PURE__*/_react["default"].createElement("aside", {
259
- style: _styles.s.sidebar
290
+ style: _objectSpread(_objectSpread({}, _styles.s.sidebar), {}, {
291
+ top: chromeOffset,
292
+ height: "calc(100vh - ".concat(chromeOffset, "px)")
293
+ })
260
294
  }, /*#__PURE__*/_react["default"].createElement(_parts.NavList, {
261
295
  items: nav,
262
296
  pathname: pathname,
@@ -281,6 +315,13 @@ function Shell(_ref) {
281
315
  open: settingsOpen,
282
316
  onClose: closeSettings,
283
317
  host: syncThemeWithHost && session.token ? themeHost : null
318
+ }), /*#__PURE__*/_react["default"].createElement(_impersonate.PowrLoginAsDialog, {
319
+ open: loginAsOpen,
320
+ onClose: function onClose() {
321
+ return setLoginAsOpen(false);
322
+ },
323
+ apiUrl: apiUrl,
324
+ projectId: projectId
284
325
  }));
285
326
  if (onboarding === false || !session.user) return content;
286
327
  return /*#__PURE__*/_react["default"].createElement(_PowrOnboardingProvider["default"], _extends({
@@ -99,6 +99,7 @@ function ProfileMenu(_ref3) {
99
99
  adminHref = _ref3.adminHref,
100
100
  Link = _ref3.Link,
101
101
  onOpenSettings = _ref3.onOpenSettings,
102
+ onLoginAs = _ref3.onLoginAs,
102
103
  onLogout = _ref3.onLogout,
103
104
  _ref3$extraItems = _ref3.extraItems,
104
105
  extraItems = _ref3$extraItems === void 0 ? [] : _ref3$extraItems;
@@ -171,7 +172,17 @@ function ProfileMenu(_ref3) {
171
172
  }, item.icon ? /*#__PURE__*/_react["default"].createElement("span", {
172
173
  "aria-hidden": true
173
174
  }, item.icon) : null, " ", item.label);
174
- }), onOpenSettings ? /*#__PURE__*/_react["default"].createElement("button", {
175
+ }), onLoginAs ? /*#__PURE__*/_react["default"].createElement("button", {
176
+ type: "button",
177
+ role: "menuitem",
178
+ onClick: function onClick() {
179
+ setOpen(false);
180
+ onLoginAs();
181
+ },
182
+ style: _styles.s.menuItem(false)
183
+ }, /*#__PURE__*/_react["default"].createElement("span", {
184
+ "aria-hidden": true
185
+ }, "\u21AA"), " Login as") : null, onOpenSettings ? /*#__PURE__*/_react["default"].createElement("button", {
175
186
  type: "button",
176
187
  role: "menuitem",
177
188
  onClick: function onClick() {
@@ -9,9 +9,9 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
9
9
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
10
10
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
11
11
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
12
- /**
13
- * Shell styles. Every colour is a `--powr-*` var with today's neutral as the
14
- * fallback — the wrapper has no palette of its own (clone-leak guardrail).
12
+ /**
13
+ * Shell styles. Every colour is a `--powr-*` var with today's neutral as the
14
+ * fallback — the wrapper has no palette of its own (clone-leak guardrail).
15
15
  */
16
16
 
17
17
  var v = exports.v = {
package/dist/sso/api.js CHANGED
@@ -27,21 +27,21 @@ function safeNextPath(next) {
27
27
  return fallback;
28
28
  }
29
29
 
30
- /**
31
- * Issue a one-time login code (caller must already be authenticated).
32
- * Host `injectProjectId` needs destination `projectId` on the body.
33
- * @param {string} apiUrl - Powr API base
34
- * @param {string} bearerToken
35
- * @param {{ projectId?: string }} [opts]
30
+ /**
31
+ * Issue a one-time login code (caller must already be authenticated).
32
+ * Host `injectProjectId` needs destination `projectId` on the body.
33
+ * @param {string} apiUrl - Powr API base
34
+ * @param {string} bearerToken
35
+ * @param {{ projectId?: string }} [opts]
36
36
  */
37
37
  function issueLoginCode(_x, _x2) {
38
38
  return _issueLoginCode.apply(this, arguments);
39
39
  }
40
- /**
41
- * Exchange loginId for session (same shape as /login).
42
- * @param {string} apiUrl
43
- * @param {string} loginId
44
- * @param {{ projectId?: string }} [opts]
40
+ /**
41
+ * Exchange loginId for session (same shape as /login).
42
+ * @param {string} apiUrl
43
+ * @param {string} loginId
44
+ * @param {{ projectId?: string }} [opts]
45
45
  */
46
46
  function _issueLoginCode() {
47
47
  _issueLoginCode = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(apiUrl, bearerToken) {
package/dist/sso/index.js CHANGED
@@ -145,22 +145,22 @@ var btnStyle = {
145
145
  cursor: "pointer"
146
146
  };
147
147
 
148
- /**
149
- * Cross-app SSO handoff UI (UrbanStall → Powr apps).
150
- * Apps keep a thin `/sso` page that renders this with `apiUrl` + `onSuccess`.
151
- *
152
- * @param {object} props
153
- * @param {string} [props.apiUrl] - Powr host. Defaults to https://powr-api.lawazia.tech
154
- * @param {string} [props.projectId] - Destination Powr id. Defaults to NEXT_PUBLIC_PROJECT_ID
155
- * @param {string} [props.appName]
156
- * @param {boolean} [props.ready=true] - Wait (e.g. auth hydrate) before exchanging code
157
- * @param {string} [props.loginHref="/login"]
158
- * @param {string} [props.loginId] - Defaults to ?loginId=
159
- * @param {string} [props.next] - Defaults to ?next=
160
- * @param {(data: object, ctx: { next: string, safeNext: string }) => void | Promise<void>} props.onSuccess
161
- * @param {string} [props.signingInTitle]
162
- * @param {string} [props.signingInMessage]
163
- * @param {string} [props.errorTitle]
148
+ /**
149
+ * Cross-app SSO handoff UI (UrbanStall → Powr apps).
150
+ * Apps keep a thin `/sso` page that renders this with `apiUrl` + `onSuccess`.
151
+ *
152
+ * @param {object} props
153
+ * @param {string} [props.apiUrl] - Powr host. Defaults to https://powr-api.lawazia.tech
154
+ * @param {string} [props.projectId] - Destination Powr id. Defaults to NEXT_PUBLIC_PROJECT_ID
155
+ * @param {string} [props.appName]
156
+ * @param {boolean} [props.ready=true] - Wait (e.g. auth hydrate) before exchanging code
157
+ * @param {string} [props.loginHref="/login"]
158
+ * @param {string} [props.loginId] - Defaults to ?loginId=
159
+ * @param {string} [props.next] - Defaults to ?next=
160
+ * @param {(data: object, ctx: { next: string, safeNext: string }) => void | Promise<void>} props.onSuccess
161
+ * @param {string} [props.signingInTitle]
162
+ * @param {string} [props.signingInMessage]
163
+ * @param {string} [props.errorTitle]
164
164
  */
165
165
  function PowrBaseSso(_ref) {
166
166
  var apiUrl = _ref.apiUrl,
@@ -79,10 +79,10 @@ function resolvePowrApiUrl(apiUrl) {
79
79
  return "";
80
80
  }
81
81
 
82
- /**
83
- * @param {string} url
84
- * @param {string[]|Array<{url?: string, projectId?: string}>} [origins] - sibling card list or origins
85
- * @returns {{ origin: string, pathname: string, search: string, hash: string, projectId: string } | null}
82
+ /**
83
+ * @param {string} url
84
+ * @param {string[]|Array<{url?: string, projectId?: string}>} [origins] - sibling card list or origins
85
+ * @returns {{ origin: string, pathname: string, search: string, hash: string, projectId: string } | null}
86
86
  */
87
87
  function matchPowrTarget(url, origins) {
88
88
  var dest = parseDest(url);
@@ -98,13 +98,13 @@ function matchPowrTarget(url, origins) {
98
98
  return dest;
99
99
  }
100
100
 
101
- /**
102
- * @deprecated Product `/powr` URLs are gone. Pass `apiUrl` + the card list as `origins`.
101
+ /**
102
+ * @deprecated Product `/powr` URLs are gone. Pass `apiUrl` + the card list as `origins`.
103
103
  */
104
104
  var DEFAULT_POWR_TARGETS = exports.DEFAULT_POWR_TARGETS = [];
105
105
 
106
- /**
107
- * Build destination `/sso?loginId=` (+ optional `next`) on the sibling app.
106
+ /**
107
+ * Build destination `/sso?loginId=` (+ optional `next`) on the sibling app.
108
108
  */
109
109
  function buildPowrSsoUrl(target, loginId) {
110
110
  var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
@@ -124,16 +124,16 @@ function openPlain(url) {
124
124
  window.open(url, "_blank", "noopener,noreferrer");
125
125
  }
126
126
 
127
- /**
128
- * Issue a login code and navigate to `/sso?loginId=`.
129
- * Host is the SDK default. Omit `apiUrl` unless this call is a real override.
130
- *
131
- * @param {string} url - Destination app URL (from the sibling card / banner)
132
- * @param {string|null|undefined} token
133
- * @param {object} [options]
134
- * @param {string} [options.apiUrl] - Override host. Do not pass product `/powr`.
135
- * @param {string} [options.projectId] - Destination Powr id (else from matched card)
136
- * @param {string[]|Array<{url?: string, projectId?: string}>} [options.origins] - The card list
127
+ /**
128
+ * Issue a login code and navigate to `/sso?loginId=`.
129
+ * Host is the SDK default. Omit `apiUrl` unless this call is a real override.
130
+ *
131
+ * @param {string} url - Destination app URL (from the sibling card / banner)
132
+ * @param {string|null|undefined} token
133
+ * @param {object} [options]
134
+ * @param {string} [options.apiUrl] - Override host. Do not pass product `/powr`.
135
+ * @param {string} [options.projectId] - Destination Powr id (else from matched card)
136
+ * @param {string[]|Array<{url?: string, projectId?: string}>} [options.origins] - The card list
137
137
  */
138
138
  function openPowrLogin(_x, _x2) {
139
139
  return _openPowrLogin.apply(this, arguments);
@@ -54,25 +54,25 @@ function systemPrefersDark() {
54
54
  return window.matchMedia(DARK_QUERY).matches;
55
55
  }
56
56
 
57
- /**
58
- * Root of the Powr theme. Mount once per app (the future `PowrBaseAppWrapper`
59
- * mounts it for you). Structure (light / dark / density) is the SDK's;
60
- * colours come from the product via `theme` and `presets`.
61
- *
62
- * With no props it writes today's neutral values, so SDK components render
63
- * exactly as before.
64
- *
65
- * @param {object} props
66
- * @param {object} [props.theme] - Product tokens. Flat `{ primary, bg, … }` (light) or `{ light: {…}, dark: {…} }`.
67
- * @param {Array<{id: string, label?: string, tokens?: object, dark?: object}>} [props.presets] - Product-named presets users may pick.
68
- * @param {"light"|"dark"|"system"} [props.scheme="light"] - Starting scheme; the user can change it (card 2 panel).
69
- * @param {"comfortable"|"compact"} [props.density="comfortable"] - Starting density.
70
- * @param {string} [props.preset] - Starting preset id.
71
- * @param {string} [props.projectId] - Cache key scope. Defaults to NEXT_PUBLIC_PROJECT_ID.
72
- * @param {boolean} [props.persist=true] - Cache choices in localStorage (cache, not truth — host save is card 3).
73
- * @param {"root"|"scoped"} [props.attach="root"] - `root` writes vars on <html>; `scoped` wraps children in one div carrying the vars.
74
- * @param {string} [props.className] - For `scoped` only.
75
- * @param {(value: {scheme: string, density: string, preset: string|null}) => void} [props.onChange] - Fires when a selector changes.
57
+ /**
58
+ * Root of the Powr theme. Mount once per app (the future `PowrBaseAppWrapper`
59
+ * mounts it for you). Structure (light / dark / density) is the SDK's;
60
+ * colours come from the product via `theme` and `presets`.
61
+ *
62
+ * With no props it writes today's neutral values, so SDK components render
63
+ * exactly as before.
64
+ *
65
+ * @param {object} props
66
+ * @param {object} [props.theme] - Product tokens. Flat `{ primary, bg, … }` (light) or `{ light: {…}, dark: {…} }`.
67
+ * @param {Array<{id: string, label?: string, tokens?: object, dark?: object}>} [props.presets] - Product-named presets users may pick.
68
+ * @param {"light"|"dark"|"system"} [props.scheme="light"] - Starting scheme; the user can change it (card 2 panel).
69
+ * @param {"comfortable"|"compact"} [props.density="comfortable"] - Starting density.
70
+ * @param {string} [props.preset] - Starting preset id.
71
+ * @param {string} [props.projectId] - Cache key scope. Defaults to NEXT_PUBLIC_PROJECT_ID.
72
+ * @param {boolean} [props.persist=true] - Cache choices in localStorage (cache, not truth — host save is card 3).
73
+ * @param {"root"|"scoped"} [props.attach="root"] - `root` writes vars on <html>; `scoped` wraps children in one div carrying the vars.
74
+ * @param {string} [props.className] - For `scoped` only.
75
+ * @param {(value: {scheme: string, density: string, preset: string|null}) => void} [props.onChange] - Fires when a selector changes.
76
76
  */
77
77
  function PowrThemeProvider(_ref) {
78
78
  var theme = _ref.theme,
@@ -304,10 +304,10 @@ var UNMOUNTED_THEME = function () {
304
304
  });
305
305
  }();
306
306
 
307
- /**
308
- * Read the theme. Outside a provider returns the neutral defaults and no-op
309
- * setters (`mounted: false`), so SDK components work in apps that have not
310
- * adopted the theme yet.
307
+ /**
308
+ * Read the theme. Outside a provider returns the neutral defaults and no-op
309
+ * setters (`mounted: false`), so SDK components work in apps that have not
310
+ * adopted the theme yet.
311
311
  */
312
312
  function usePowrTheme() {
313
313
  var ctx = (0, _react.useContext)(PowrThemeContext);
@@ -24,16 +24,16 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
24
24
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
25
25
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
26
26
  function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
27
- /**
28
- * User-level theme selectors: scheme · density · product preset.
29
- *
30
- * Reads and writes through `usePowrTheme()`, so it needs a `PowrThemeProvider`
31
- * above it. Legacy apps mount this inside their own Settings page; the
32
- * wrapper opens it in a drawer. Presets come from the product — this panel
33
- * never invents colours (no colour wheel).
34
- *
35
- * `onSave` is the hook for card 3 (host `/users/me/preferences`). Until then
36
- * changes are live + cached in localStorage by the provider.
27
+ /**
28
+ * User-level theme selectors: scheme · density · product preset.
29
+ *
30
+ * Reads and writes through `usePowrTheme()`, so it needs a `PowrThemeProvider`
31
+ * above it. Legacy apps mount this inside their own Settings page; the
32
+ * wrapper opens it in a drawer. Presets come from the product — this panel
33
+ * never invents colours (no colour wheel).
34
+ *
35
+ * `onSave` is the hook for card 3 (host `/users/me/preferences`). Until then
36
+ * changes are live + cached in localStorage by the provider.
37
37
  */
38
38
 
39
39
  var SCHEME_LABELS = {
@@ -169,15 +169,15 @@ function presetSwatches(preset, dark) {
169
169
  return [t.bg, t.surface, t.primary, t.text].filter(Boolean);
170
170
  }
171
171
 
172
- /**
173
- * @param {object} props
174
- * @param {string} [props.title="Appearance"]
175
- * @param {boolean} [props.showScheme=true]
176
- * @param {boolean} [props.showDensity=true]
177
- * @param {boolean} [props.showPresets=true] - Hidden automatically when the product passed no presets.
178
- * @param {(value: {scheme, density, preset}) => void|Promise<void>} [props.onSave] - Card 3: host save. Shows a Save button when given.
179
- * @param {boolean} [props.saving]
180
- * @param {string} [props.saveLabel="Save"]
172
+ /**
173
+ * @param {object} props
174
+ * @param {string} [props.title="Appearance"]
175
+ * @param {boolean} [props.showScheme=true]
176
+ * @param {boolean} [props.showDensity=true]
177
+ * @param {boolean} [props.showPresets=true] - Hidden automatically when the product passed no presets.
178
+ * @param {(value: {scheme, density, preset}) => void|Promise<void>} [props.onSave] - Card 3: host save. Shows a Save button when given.
179
+ * @param {boolean} [props.saving]
180
+ * @param {string} [props.saveLabel="Save"]
181
181
  */
182
182
  function PowrThemeSettings(_ref2) {
183
183
  var _ref2$title = _ref2.title,
@@ -19,13 +19,13 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
19
19
  function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
20
20
  function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
21
21
  function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
22
- /**
23
- * Theme preference on the Powr host — `GET/PUT /users/me/preferences`.
24
- *
25
- * localStorage is the cache before first paint; the host is the truth once
26
- * the user is logged in. Pull once per token, apply what the host has, and
27
- * write on Save. Same thesis as login: host stores, SDK reads/writes,
28
- * products omit `apiUrl`.
22
+ /**
23
+ * Theme preference on the Powr host — `GET/PUT /users/me/preferences`.
24
+ *
25
+ * localStorage is the cache before first paint; the host is the truth once
26
+ * the user is logged in. Pull once per token, apply what the host has, and
27
+ * write on Save. Same thesis as login: host stores, SDK reads/writes,
28
+ * products omit `apiUrl`.
29
29
  */
30
30
 
31
31
  var ENDPOINT = "/users/me/preferences";
@@ -80,15 +80,15 @@ function _fetchThemePreference() {
80
80
  function saveThemePreference() {
81
81
  return _saveThemePreference.apply(this, arguments);
82
82
  }
83
- /**
84
- * Keep the mounted `PowrThemeProvider` in sync with the host for one user.
85
- *
86
- * @param {object} opts
87
- * @param {string|null} [opts.token] - Powr JWT. No token → nothing happens (cache only).
88
- * @param {string} [opts.apiUrl] - Leave unset; SDK default host.
89
- * @param {string} [opts.projectId] - Defaults to NEXT_PUBLIC_PROJECT_ID.
90
- * @param {boolean} [opts.enabled=true]
91
- * @returns {{ loaded: boolean, saving: boolean, error: string|null, save: (theme?) => Promise<void>, refresh: () => Promise<void> }}
83
+ /**
84
+ * Keep the mounted `PowrThemeProvider` in sync with the host for one user.
85
+ *
86
+ * @param {object} opts
87
+ * @param {string|null} [opts.token] - Powr JWT. No token → nothing happens (cache only).
88
+ * @param {string} [opts.apiUrl] - Leave unset; SDK default host.
89
+ * @param {string} [opts.projectId] - Defaults to NEXT_PUBLIC_PROJECT_ID.
90
+ * @param {boolean} [opts.enabled=true]
91
+ * @returns {{ loaded: boolean, saving: boolean, error: string|null, save: (theme?) => Promise<void>, refresh: () => Promise<void> }}
92
92
  */
93
93
  function _saveThemePreference() {
94
94
  _saveThemePreference = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {