@webority/web-core 0.84.0 → 0.85.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
@@ -310,6 +310,25 @@ Vite 7 and earlier `esbuild: { pure: ["Logger.debug"] }`. This matches the call
310
310
  already filtered by `logLevel`. On the web, track the matched route pattern with `trackScreen`, never the
311
311
  concrete URL.
312
312
 
313
+ ## Design sample
314
+
315
+ A Canvas compare opens a staging page with a `designSample` key in its address, and a person can open
316
+ one the same way. The ticket is the proof a product's API needs to answer its sample data in place of
317
+ the live answers. `readDesignSampleTicket()` returns it, or `null`. The first read copies the address
318
+ key into `sessionStorage` (`webority.designSample`) and leaves the address as it is; later reads answer
319
+ the stored ticket, so it survives in-app navigation and redirects and ends with the tab.
320
+
321
+ `applyDesignSample(client)` is wired into `userClient` and `publicClient`: every request carries the
322
+ `X-Design-Sample` header when a ticket exists and the request does not set one itself. A header the
323
+ request sets by hand wins.
324
+
325
+ The ticket is never read in `Production`: `readDesignSampleTicket()` returns `null` there, whatever the
326
+ address holds, and no header is sent. The Delivery package also refuses to start a Production head with
327
+ the mode on, so the two checks are independent.
328
+
329
+ The design sample exists on the web only; `@webority/mobile-core` has no counterpart. This package stays
330
+ TypeScript, a recorded deviation from `react.md`, which asks for JavaScript.
331
+
313
332
  ## Develop
314
333
 
315
334
  ```bash
@@ -0,0 +1 @@
1
+ import{getConfigValue as e}from"../config/index.js";var t=`designSample`,n=`X-Design-Sample`,r=`webority.designSample`,i=!1,a=()=>{if(e(`environment`)===`Production`)return null;if(!i){i=!0;let e=new URLSearchParams(window.location.search).get(t);e&&sessionStorage.setItem(r,e)}return sessionStorage.getItem(r)},o=e=>{e.interceptors.request.use(e=>{let t=a();return t&&!e.headers.has(`X-Design-Sample`)&&e.headers.set(n,t),e})};export{n as DESIGN_SAMPLE_HEADER,t as DESIGN_SAMPLE_QUERY_KEY,r as DESIGN_SAMPLE_STORAGE_KEY,o as applyDesignSample,a as readDesignSampleTicket};
package/dist/api/index.js CHANGED
@@ -1 +1 @@
1
- import{ACCOUNT_ID_HEADER as e,CLIENT_BUILD_HEADER as t,CLIENT_KIND as n,CLIENT_KIND_HEADER as r,getClientBuild as i}from"./clientHeaders.js";import{MIN_APP_VERSION_HEADER as a,addMinAppVersionListener as o,getMinAppVersion as s}from"./minAppVersion.js";import{applyRequestDefaults as c,newCorrelationId as l}from"./requestDefaults.js";import{WORKSPACE_CHANGED_CODE as u,WorkspaceChangedError as d,isWorkspaceChangedError as f}from"./workspaceChanged.js";import{IDEMPOTENCY_KEY_HEADER as p,attachRetry as m,isNeverSentError as h,isRetryableFailure as g,isRetryableStatus as _,retryAfterMs as v}from"./retry.js";import{REFRESH_LOCK_NAME as y,withCrossTabRefreshLock as b}from"./crossTabRefreshLock.js";import x from"./publicClient.js";import{SIGN_OUT_REASON_HEADER as S,injectStore as C,injectUserAuth as w,refreshAccessToken as T,resetRefreshState as E}from"./tokenRefresh.js";import D,{RequestOfflineError as O,SESSION_TERMINATION_CODES as k}from"./userClient.js";import{initUserAuth as A}from"../initUserAuth.js";export{e as ACCOUNT_ID_HEADER,t as CLIENT_BUILD_HEADER,n as CLIENT_KIND,r as CLIENT_KIND_HEADER,p as IDEMPOTENCY_KEY_HEADER,a as MIN_APP_VERSION_HEADER,y as REFRESH_LOCK_NAME,O as RequestOfflineError,k as SESSION_TERMINATION_CODES,S as SIGN_OUT_REASON_HEADER,u as WORKSPACE_CHANGED_CODE,d as WorkspaceChangedError,o as addMinAppVersionListener,c as applyRequestDefaults,m as attachRetry,i as getClientBuild,s as getMinAppVersion,A as initUserAuth,C as injectStore,w as injectUserAuth,h as isNeverSentError,g as isRetryableFailure,_ as isRetryableStatus,f as isWorkspaceChangedError,l as newCorrelationId,x as publicClient,T as refreshAccessToken,E as resetRefreshState,v as retryAfterMs,D as userClient,b as withCrossTabRefreshLock};
1
+ import{ACCOUNT_ID_HEADER as e,CLIENT_BUILD_HEADER as t,CLIENT_KIND as n,CLIENT_KIND_HEADER as r,getClientBuild as i}from"./clientHeaders.js";import{DESIGN_SAMPLE_HEADER as a,DESIGN_SAMPLE_QUERY_KEY as o,DESIGN_SAMPLE_STORAGE_KEY as s,applyDesignSample as c,readDesignSampleTicket as l}from"./designSample.js";import{MIN_APP_VERSION_HEADER as u,addMinAppVersionListener as d,getMinAppVersion as f}from"./minAppVersion.js";import{applyRequestDefaults as p,newCorrelationId as m}from"./requestDefaults.js";import{WORKSPACE_CHANGED_CODE as h,WorkspaceChangedError as g,isWorkspaceChangedError as _}from"./workspaceChanged.js";import{IDEMPOTENCY_KEY_HEADER as v,attachRetry as y,isNeverSentError as b,isRetryableFailure as x,isRetryableStatus as S,retryAfterMs as C}from"./retry.js";import{REFRESH_LOCK_NAME as w,withCrossTabRefreshLock as T}from"./crossTabRefreshLock.js";import E from"./publicClient.js";import{SIGN_OUT_REASON_HEADER as D,injectStore as O,injectUserAuth as k,refreshAccessToken as A,resetRefreshState as j}from"./tokenRefresh.js";import M,{RequestOfflineError as N,SESSION_TERMINATION_CODES as P}from"./userClient.js";import{initUserAuth as F}from"../initUserAuth.js";export{e as ACCOUNT_ID_HEADER,t as CLIENT_BUILD_HEADER,n as CLIENT_KIND,r as CLIENT_KIND_HEADER,a as DESIGN_SAMPLE_HEADER,o as DESIGN_SAMPLE_QUERY_KEY,s as DESIGN_SAMPLE_STORAGE_KEY,v as IDEMPOTENCY_KEY_HEADER,u as MIN_APP_VERSION_HEADER,w as REFRESH_LOCK_NAME,N as RequestOfflineError,P as SESSION_TERMINATION_CODES,D as SIGN_OUT_REASON_HEADER,h as WORKSPACE_CHANGED_CODE,g as WorkspaceChangedError,d as addMinAppVersionListener,c as applyDesignSample,p as applyRequestDefaults,y as attachRetry,i as getClientBuild,f as getMinAppVersion,F as initUserAuth,O as injectStore,k as injectUserAuth,b as isNeverSentError,x as isRetryableFailure,S as isRetryableStatus,_ as isWorkspaceChangedError,m as newCorrelationId,E as publicClient,l as readDesignSampleTicket,A as refreshAccessToken,j as resetRefreshState,C as retryAfterMs,M as userClient,T as withCrossTabRefreshLock};
@@ -1 +1 @@
1
- import{Logger as e}from"../logger/logger.js";import{applyConfiguredBaseUrl as t}from"./baseUrl.js";import{applyClientHeaders as n}from"./clientHeaders.js";import{readMinAppVersion as r}from"./minAppVersion.js";import{sendFormDataAsMultipart as i}from"./multipart.js";import{applyRequestDefaults as a}from"./requestDefaults.js";import{responseBodyText as o}from"./responseBodyText.js";import{attachRetry as s}from"./retry.js";import c from"axios";var l=c.create({headers:{"Content-Type":`application/json`,Accept:`application/json`}});t(l),a(l),i(l),r(l),s(l),l.interceptors.request.use(t=>(e.info(`Request: ${t.method?.toUpperCase()} ${t.url}`),t),t=>{let n=t instanceof Error?t.message:String(t);return e.error(`Request error:`,n),Promise.reject(t)}),n(l),l.interceptors.response.use(t=>(e.info(`Response: ${t.status} from ${t.config.url}`),t),t=>{if(c.isCancel(t))return Promise.reject(t);if(c.isAxiosError(t)){let n=t.config;if(n?.skipErrorLog)return Promise.reject(t);t.response?e.error(`Response error: ${o(t.response.data,t.message)}, URL: ${n?.url}, Status: ${t.response.status}`):e.error(`Network error or no response from server: ${t.message}, URL: ${n?.url}`)}else{let n=t instanceof Error?t.message:String(t);e.error(`Unknown response error: ${n}`)}return Promise.reject(t)});export{l as default};
1
+ import{Logger as e}from"../logger/logger.js";import{applyConfiguredBaseUrl as t}from"./baseUrl.js";import{applyClientHeaders as n}from"./clientHeaders.js";import{applyDesignSample as r}from"./designSample.js";import{readMinAppVersion as i}from"./minAppVersion.js";import{sendFormDataAsMultipart as a}from"./multipart.js";import{applyRequestDefaults as o}from"./requestDefaults.js";import{responseBodyText as s}from"./responseBodyText.js";import{attachRetry as c}from"./retry.js";import l from"axios";var u=l.create({headers:{"Content-Type":`application/json`,Accept:`application/json`}});t(u),o(u),a(u),i(u),c(u),u.interceptors.request.use(t=>(e.info(`Request: ${t.method?.toUpperCase()} ${t.url}`),t),t=>{let n=t instanceof Error?t.message:String(t);return e.error(`Request error:`,n),Promise.reject(t)}),n(u),r(u),u.interceptors.response.use(t=>(e.info(`Response: ${t.status} from ${t.config.url}`),t),t=>{if(l.isCancel(t))return Promise.reject(t);if(l.isAxiosError(t)){let n=t.config;if(n?.skipErrorLog)return Promise.reject(t);t.response?e.error(`Response error: ${s(t.response.data,t.message)}, URL: ${n?.url}, Status: ${t.response.status}`):e.error(`Network error or no response from server: ${t.message}, URL: ${n?.url}`)}else{let n=t instanceof Error?t.message:String(t);e.error(`Unknown response error: ${n}`)}return Promise.reject(t)});export{u as default};
@@ -1 +1 @@
1
- import{Logger as e}from"../logger/logger.js";import{ACCESS_TOKEN_KEY as t,getToken as n}from"../auth/authStore.js";import{getLastKnownNetworkStatus as r}from"../network/networkStatus.js";import{applyConfiguredBaseUrl as i}from"./baseUrl.js";import{applyClientHeaders as a,readAccountId as o,stampAccountId as s}from"./clientHeaders.js";import{readMinAppVersion as c}from"./minAppVersion.js";import{sendFormDataAsMultipart as l}from"./multipart.js";import{applyRequestDefaults as u}from"./requestDefaults.js";import{responseBodyText as d}from"./responseBodyText.js";import{WorkspaceChangedError as f,isWorkspaceChangedResponse as p,workspaceChangedFromResponse as m}from"./workspaceChanged.js";import{attachRetry as h}from"./retry.js";import{SIGN_OUT_REASON_HEADER as g,beginSessionReplacement as _,currentTokenIfReplaced as v,endSessionAndLogout as y,getAccountIdProvider as b,getErrorMessage as x,getRefreshPath as S,injectStore as C,injectUserAuth as w,isRefreshInFlight as T,queueBehindRefresh as E,readSignOutReason as D,refreshAccessToken as O,resetRefreshState as k,storeReplacementSession as A,waitForSessionReplacement as j}from"./tokenRefresh.js";import M,{AxiosHeaders as N}from"axios";var P=class e extends Error{constructor(t=`Request blocked: device is offline`){super(t),this.name=`RequestOfflineError`,Object.setPrototypeOf(this,e.prototype)}},F=class e extends Error{constructor(){super(`No access token available`),this.name=`NoAccessTokenError`,Object.setPrototypeOf(this,e.prototype)}},I={TERMINATED:`SESSION_TERMINATED`,EXPIRED:`SESSION_EXPIRED`},L=new Set(Object.values(I)),R=`x-security-stamp-invalid`,z=e=>{if(!e||typeof e!=`object`)return!1;let t=e.get,n=typeof t==`function`?t.call(e,R):e[R];return String(n).toLowerCase()===`true`},B=e=>{if(!e||typeof e!=`object`)return;let t=e,n=t.error,r=[t.code,t.errorCode,n&&typeof n==`object`?n.code:void 0];for(let e of r)if(typeof e==`string`&&L.has(e))return e},V=e=>{e?._endReplacement?.(),e&&(e._endReplacement=void 0)},H=e=>{let t=e.headers instanceof N?e.headers.get(`Authorization`):void 0;return typeof t==`string`&&t.startsWith(`Bearer `)?t.slice(7):null},U=M.create({headers:{"Content-Type":`application/json`}});c(U),h(U);var W=(e,t)=>{e.headers instanceof N?e.headers.set(`Authorization`,`Bearer ${t}`):e.headers=N.from({...e.headers,Authorization:`Bearer ${t}`})},G=e=>{let t=S();return!!t&&!!e?.includes(t)};i(U),u(U),l(U),a(U),U.interceptors.request.use(async i=>{if(V(i),(await r()).isConnected===!1)return e.warn(`Request blocked: browser is offline. URL: ${i.url}`),Promise.reject(new P);try{if(G(i.url))return i;await s(i,b());let r=await n(t);if(!r?.token)throw new F;let a=Date.now();return Date.parse(r.expiry)<=a+30*1e3?(e.info(`Access token expired or about to expire, refreshing before request`),W(i,await O())):W(i,r.token),i.replacesSession&&(i._endReplacement=_()),i}catch(t){return t instanceof F?e.info(`Request not sent: signed out. URL: ${i.url}`):e.error(`Failed to attach token:`,x(t)),Promise.reject(t)}},t=>(e.error(`Request error:`,x(t)),Promise.reject(t))),U.interceptors.response.use(async e=>{let t=e.config;if(t._endReplacement)try{await A(e.data)}finally{V(t)}return e},async t=>{if(V(t?.config),M.isCancel(t)||t instanceof P||t instanceof F||t instanceof f)return Promise.reject(t);if(!M.isAxiosError(t))return e.error(`Non-axios error in response interceptor: ${x(t)}`),Promise.reject(t);let n=t,r=n.config;if(!n.response)return r?.skipErrorLog||e.error(`Network error or no response from server: ${n.message}, URL: ${r?.url}`),Promise.reject(t);if(p(n))return e.info(`Request refused: the workspace changed after it was made. URL: ${r?.url}`),Promise.reject(m(n));if(n.response.status===401&&r&&!r._replayedWithCurrentToken&&!r.replacesSession&&!G(r.url)&&(await j(),await v(H(r))))return(r._accountId??null)===await o(b())?(e.info(`Session changed while the request was in flight; sending it again. URL: ${r.url}`),r._replayedWithCurrentToken=!0,U(r)):(e.info(`Session moved to another workspace while the request was in flight; not sending it again. URL: ${r.url}`),Promise.reject(new f(void 0,{config:r,cause:t})));if(n.response.status===401&&r&&!r._retry){if(G(r.url))return Promise.reject(t);let i=D(n.response.headers),a=B(n.response.data)??(z(n.response.headers)||i!==null?I.TERMINATED:void 0);if(a)return e.warn(`Session ${a}, logging out without refresh. URL: ${r.url}`),k(),await y(`terminated`,i),Promise.reject(t);if(e.warn(`Unauthorized URL: ${r.url}`),r._retry=!0,T())return E().then(t=>(e.info(`Retrying request after token refresh:`,r.url),W(r,t),U(r))).catch(t=>(t instanceof f||e.error(`Failed to retry request after token refresh:`,x(t)),Promise.reject(t)));try{return W(r,await O()),U(r)}catch(e){return Promise.reject(e)}}return r?.skipErrorLog||e.error(`Response error: ${d(n.response?.data,n.message)}, URL: ${r?.url}, Status: ${n.response.status}`),Promise.reject(t)});export{P as RequestOfflineError,R as SESSION_INVALID_HEADER,I as SESSION_TERMINATION_CODES,g as SIGN_OUT_REASON_HEADER,U as default,C as injectStore,w as injectUserAuth,k as resetRefreshState};
1
+ import{Logger as e}from"../logger/logger.js";import{ACCESS_TOKEN_KEY as t,getToken as n}from"../auth/authStore.js";import{getLastKnownNetworkStatus as r}from"../network/networkStatus.js";import{applyConfiguredBaseUrl as i}from"./baseUrl.js";import{applyClientHeaders as a,readAccountId as o,stampAccountId as s}from"./clientHeaders.js";import{applyDesignSample as c}from"./designSample.js";import{readMinAppVersion as l}from"./minAppVersion.js";import{sendFormDataAsMultipart as u}from"./multipart.js";import{applyRequestDefaults as d}from"./requestDefaults.js";import{responseBodyText as f}from"./responseBodyText.js";import{WorkspaceChangedError as p,isWorkspaceChangedResponse as m,workspaceChangedFromResponse as h}from"./workspaceChanged.js";import{attachRetry as g}from"./retry.js";import{SIGN_OUT_REASON_HEADER as _,beginSessionReplacement as v,currentTokenIfReplaced as y,endSessionAndLogout as b,getAccountIdProvider as x,getErrorMessage as S,getRefreshPath as C,injectStore as w,injectUserAuth as T,isRefreshInFlight as E,queueBehindRefresh as D,readSignOutReason as O,refreshAccessToken as k,resetRefreshState as A,storeReplacementSession as j,waitForSessionReplacement as M}from"./tokenRefresh.js";import N,{AxiosHeaders as P}from"axios";var F=class e extends Error{constructor(t=`Request blocked: device is offline`){super(t),this.name=`RequestOfflineError`,Object.setPrototypeOf(this,e.prototype)}},I=class e extends Error{constructor(){super(`No access token available`),this.name=`NoAccessTokenError`,Object.setPrototypeOf(this,e.prototype)}},L={TERMINATED:`SESSION_TERMINATED`,EXPIRED:`SESSION_EXPIRED`},R=new Set(Object.values(L)),z=`x-security-stamp-invalid`,B=e=>{if(!e||typeof e!=`object`)return!1;let t=e.get,n=typeof t==`function`?t.call(e,z):e[z];return String(n).toLowerCase()===`true`},V=e=>{if(!e||typeof e!=`object`)return;let t=e,n=t.error,r=[t.code,t.errorCode,n&&typeof n==`object`?n.code:void 0];for(let e of r)if(typeof e==`string`&&R.has(e))return e},H=e=>{e?._endReplacement?.(),e&&(e._endReplacement=void 0)},U=e=>{let t=e.headers instanceof P?e.headers.get(`Authorization`):void 0;return typeof t==`string`&&t.startsWith(`Bearer `)?t.slice(7):null},W=N.create({headers:{"Content-Type":`application/json`}});l(W),g(W);var G=(e,t)=>{e.headers instanceof P?e.headers.set(`Authorization`,`Bearer ${t}`):e.headers=P.from({...e.headers,Authorization:`Bearer ${t}`})},K=e=>{let t=C();return!!t&&!!e?.includes(t)};i(W),d(W),u(W),a(W),c(W),W.interceptors.request.use(async i=>{if(H(i),(await r()).isConnected===!1)return e.warn(`Request blocked: browser is offline. URL: ${i.url}`),Promise.reject(new F);try{if(K(i.url))return i;await s(i,x());let r=await n(t);if(!r?.token)throw new I;let a=Date.now();return Date.parse(r.expiry)<=a+30*1e3?(e.info(`Access token expired or about to expire, refreshing before request`),G(i,await k())):G(i,r.token),i.replacesSession&&(i._endReplacement=v()),i}catch(t){return t instanceof I?e.info(`Request not sent: signed out. URL: ${i.url}`):e.error(`Failed to attach token:`,S(t)),Promise.reject(t)}},t=>(e.error(`Request error:`,S(t)),Promise.reject(t))),W.interceptors.response.use(async e=>{let t=e.config;if(t._endReplacement)try{await j(e.data)}finally{H(t)}return e},async t=>{if(H(t?.config),N.isCancel(t)||t instanceof F||t instanceof I||t instanceof p)return Promise.reject(t);if(!N.isAxiosError(t))return e.error(`Non-axios error in response interceptor: ${S(t)}`),Promise.reject(t);let n=t,r=n.config;if(!n.response)return r?.skipErrorLog||e.error(`Network error or no response from server: ${n.message}, URL: ${r?.url}`),Promise.reject(t);if(m(n))return e.info(`Request refused: the workspace changed after it was made. URL: ${r?.url}`),Promise.reject(h(n));if(n.response.status===401&&r&&!r._replayedWithCurrentToken&&!r.replacesSession&&!K(r.url)&&(await M(),await y(U(r))))return(r._accountId??null)===await o(x())?(e.info(`Session changed while the request was in flight; sending it again. URL: ${r.url}`),r._replayedWithCurrentToken=!0,W(r)):(e.info(`Session moved to another workspace while the request was in flight; not sending it again. URL: ${r.url}`),Promise.reject(new p(void 0,{config:r,cause:t})));if(n.response.status===401&&r&&!r._retry){if(K(r.url))return Promise.reject(t);let i=O(n.response.headers),a=V(n.response.data)??(B(n.response.headers)||i!==null?L.TERMINATED:void 0);if(a)return e.warn(`Session ${a}, logging out without refresh. URL: ${r.url}`),A(),await b(`terminated`,i),Promise.reject(t);if(e.warn(`Unauthorized URL: ${r.url}`),r._retry=!0,E())return D().then(t=>(e.info(`Retrying request after token refresh:`,r.url),G(r,t),W(r))).catch(t=>(t instanceof p||e.error(`Failed to retry request after token refresh:`,S(t)),Promise.reject(t)));try{return G(r,await k()),W(r)}catch(e){return Promise.reject(e)}}return r?.skipErrorLog||e.error(`Response error: ${f(n.response?.data,n.message)}, URL: ${r?.url}, Status: ${n.response.status}`),Promise.reject(t)});export{F as RequestOfflineError,z as SESSION_INVALID_HEADER,L as SESSION_TERMINATION_CODES,_ as SIGN_OUT_REASON_HEADER,W as default,w as injectStore,T as injectUserAuth,A as resetRefreshState};
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{DEFAULT_BUILD_CHECK_INTERVAL_MS as e,DEFAULT_CORRELATION_ID_HEADER as t,DEFAULT_LOG_LEVEL as n,DEFAULT_RETRIES as r,DEFAULT_TIMEOUT_MS as i,DEFAULT_VERSION_URL as a,getConfig as o,getConfigValue as s,resetConfig as c,setConfig as l}from"./config/index.js";import{Logger as u,configureLogger as d,getDeviceContext as f,setDeviceContext as p,setRemoteLogger as m}from"./logger/logger.js";import{decodeJWT as h,getJWTExpiry as g,isJWTExpired as _}from"./auth/jwt.js";import{ACCESS_TOKEN_KEY as v,LEGACY_REFRESH_TOKEN_LIFETIME_MS as y,REFRESH_TOKEN_KEY as b,SESSION_USER_KEY as x,addSessionEndedListener as S,clearSession as C,getKeepSignedIn as w,getSessionUser as T,getToken as E,hasSession as D,hasSessionEndedInTab as O,removeSessionUser as k,removeToken as A,setKeepSignedIn as j,setLegacyTokenKeys as M,storeSessionUser as N,storeToken as P}from"./auth/authStore.js";import{addNetworkStatusListener as F,getNetworkStatus as I,setNetworkStatusImplementation as L,useNetworkStatus as R}from"./network/networkStatus.js";import{ACCOUNT_ID_HEADER as z,CLIENT_BUILD_HEADER as B,CLIENT_KIND as V,CLIENT_KIND_HEADER as H,getClientBuild as U}from"./api/clientHeaders.js";import{MIN_APP_VERSION_HEADER as W,addMinAppVersionListener as G,getMinAppVersion as K}from"./api/minAppVersion.js";import{applyRequestDefaults as q,newCorrelationId as J}from"./api/requestDefaults.js";import{WORKSPACE_CHANGED_CODE as Y,WorkspaceChangedError as X,isWorkspaceChangedError as Z}from"./api/workspaceChanged.js";import{IDEMPOTENCY_KEY_HEADER as Q,attachRetry as $,isNeverSentError as ee,isRetryableFailure as te,isRetryableStatus as ne,retryAfterMs as re}from"./api/retry.js";import{REFRESH_LOCK_NAME as ie,withCrossTabRefreshLock as ae}from"./api/crossTabRefreshLock.js";import oe from"./api/publicClient.js";import{SIGN_OUT_REASON_HEADER as se,injectStore as ce,injectUserAuth as le,refreshAccessToken as ue,resetRefreshState as de}from"./api/tokenRefresh.js";import fe,{RequestOfflineError as pe,SESSION_TERMINATION_CODES as me}from"./api/userClient.js";import{initUserAuth as he}from"./initUserAuth.js";import{CONTRACT_ERROR_CODE as ge,NETWORK_CODE as _e,OFFLINE_CODE as ve,OFFLINE_MESSAGE as ye,REQUEST_CANCELED_CODE as be,SERVER_FAILURE_MESSAGE as xe,TIMEOUT_CODE as Se,TIMEOUT_MESSAGE as Ce,UNEXPECTED_MESSAGE as we,UNREACHABLE_MESSAGE as Te,apiErrorMessage as Ee,extractApiError as De,isApiError as Oe,isNoResponse as ke,toFieldPath as Ae}from"./errors/extractApiError.js";import{configureFormatters as je,getFormatterConfig as Me}from"./formatters/formatConfig.js";import{formatCurrency as Ne}from"./formatters/currency.js";import{addDays as Pe}from"./formatters/dateMath.js";import{formatDate as Fe,formatDateTime as Ie,formatMinor as Le,formatNumber as Re,formatPercent as ze,formatRelative as Be,formatTime as Ve}from"./formatters/house.js";import{initWebority as He}from"./initSDK.js";import{createApiBaseQuery as Ue}from"./query/apiBaseQuery.js";import{APP_API_DEFAULTS as We,createAppApi as Ge}from"./query/createAppApi.js";import{setupApiListeners as Ke}from"./query/listeners.js";import{buildListQuery as qe,getNextPageParam as Je,getPreviousPageParam as Ye,hasNextPage as Xe,hasPreviousPage as Ze}from"./query/paging.js";import{LIST_TAG_ID as Qe,itemTag as $e,listTag as et,providesList as tt,providesPagedList as nt}from"./query/tags.js";import{errorToastMiddleware as rt,isSilentRejection as it}from"./redux/errorToastMiddleware.js";import{createRootReducer as at,resetState as ot}from"./redux/rootReducer.js";import{SERIALIZABLE_IGNORED_ACTION_PATHS as st}from"./redux/serializableCheck.js";import{hasRecentlyReloaded as ct,importWithReload as lt,isChunkLoadError as ut,lazyWithReload as dt,markReloaded as ft}from"./router/chunkReload.js";import{hasPermission as pt}from"./router/permissions.js";import{RETURN_TO_PARAM as mt,buildLoginPath as ht,getReturnTo as gt,toSafeReturnTo as _t}from"./router/returnTo.js";import{PublicOnly as vt,RequireAuth as yt,RequirePermission as bt}from"./router/guards.js";import{publicOnly as xt,requireAuth as St,requirePermission as Ct,withGuards as wt}from"./router/loaders.js";import{classifyRouteError as Tt,useRouteErrorReport as Et}from"./router/routeError.js";import{staticUrl as Dt}from"./static/index.js";import{Storage as Ot,isStorageAvailable as kt,setStorageImplementation as At,syncStorage as jt}from"./storage/index.js";import{isBuildBelowMinimum as Mt,parseBuildNumber as Nt}from"./versionCheck/buildNumber.js";import{addDeployedBuildListener as Pt,getNewerDeployedBuild as Ft,startDeployedBuildCheck as It}from"./versionCheck/deployedBuild.js";import{installReloadOnNavigate as Lt,isUpdateAvailable as Rt,useVersionCheck as zt}from"./versionCheck/index.js";export{v as ACCESS_TOKEN_KEY,z as ACCOUNT_ID_HEADER,We as APP_API_DEFAULTS,B as CLIENT_BUILD_HEADER,V as CLIENT_KIND,H as CLIENT_KIND_HEADER,ge as CONTRACT_ERROR_CODE,e as DEFAULT_BUILD_CHECK_INTERVAL_MS,t as DEFAULT_CORRELATION_ID_HEADER,n as DEFAULT_LOG_LEVEL,r as DEFAULT_RETRIES,i as DEFAULT_TIMEOUT_MS,a as DEFAULT_VERSION_URL,Q as IDEMPOTENCY_KEY_HEADER,y as LEGACY_REFRESH_TOKEN_LIFETIME_MS,Qe as LIST_TAG_ID,u as Logger,W as MIN_APP_VERSION_HEADER,_e as NETWORK_CODE,ve as OFFLINE_CODE,ye as OFFLINE_MESSAGE,vt as PublicOnly,ie as REFRESH_LOCK_NAME,b as REFRESH_TOKEN_KEY,be as REQUEST_CANCELED_CODE,mt as RETURN_TO_PARAM,pe as RequestOfflineError,yt as RequireAuth,bt as RequirePermission,st as SERIALIZABLE_IGNORED_ACTION_PATHS,xe as SERVER_FAILURE_MESSAGE,me as SESSION_TERMINATION_CODES,x as SESSION_USER_KEY,se as SIGN_OUT_REASON_HEADER,Ot as Storage,Se as TIMEOUT_CODE,Ce as TIMEOUT_MESSAGE,we as UNEXPECTED_MESSAGE,Te as UNREACHABLE_MESSAGE,Y as WORKSPACE_CHANGED_CODE,X as WorkspaceChangedError,Pe as addDays,Pt as addDeployedBuildListener,G as addMinAppVersionListener,F as addNetworkStatusListener,S as addSessionEndedListener,Ee as apiErrorMessage,q as applyRequestDefaults,$ as attachRetry,qe as buildListQuery,ht as buildLoginPath,Tt as classifyRouteError,C as clearSession,je as configureFormatters,d as configureLogger,Ue as createApiBaseQuery,Ge as createAppApi,at as createRootReducer,h as decodeJWT,rt as errorToastMiddleware,De as extractApiError,Ne as formatCurrency,Fe as formatDate,Ie as formatDateTime,Le as formatMinor,Re as formatNumber,ze as formatPercent,Be as formatRelative,Ve as formatTime,U as getClientBuild,o as getConfig,s as getConfigValue,f as getDeviceContext,Me as getFormatterConfig,g as getJWTExpiry,w as getKeepSignedIn,K as getMinAppVersion,I as getNetworkStatus,Ft as getNewerDeployedBuild,Je as getNextPageParam,Ye as getPreviousPageParam,gt as getReturnTo,T as getSessionUser,E as getToken,Xe as hasNextPage,pt as hasPermission,Ze as hasPreviousPage,ct as hasRecentlyReloaded,D as hasSession,O as hasSessionEndedInTab,lt as importWithReload,he as initUserAuth,He as initWebority,ce as injectStore,le as injectUserAuth,Lt as installReloadOnNavigate,Oe as isApiError,Mt as isBuildBelowMinimum,ut as isChunkLoadError,_ as isJWTExpired,ee as isNeverSentError,ke as isNoResponse,te as isRetryableFailure,ne as isRetryableStatus,it as isSilentRejection,kt as isStorageAvailable,Rt as isUpdateAvailable,Z as isWorkspaceChangedError,$e as itemTag,dt as lazyWithReload,et as listTag,ft as markReloaded,J as newCorrelationId,Nt as parseBuildNumber,tt as providesList,nt as providesPagedList,oe as publicClient,xt as publicOnly,ue as refreshAccessToken,k as removeSessionUser,A as removeToken,St as requireAuth,Ct as requirePermission,c as resetConfig,de as resetRefreshState,ot as resetState,re as retryAfterMs,l as setConfig,p as setDeviceContext,j as setKeepSignedIn,M as setLegacyTokenKeys,L as setNetworkStatusImplementation,m as setRemoteLogger,At as setStorageImplementation,Ke as setupApiListeners,It as startDeployedBuildCheck,Dt as staticUrl,N as storeSessionUser,P as storeToken,jt as syncStorage,Ae as toFieldPath,_t as toSafeReturnTo,R as useNetworkStatus,Et as useRouteErrorReport,zt as useVersionCheck,fe as userClient,ae as withCrossTabRefreshLock,wt as withGuards};
1
+ import{DEFAULT_BUILD_CHECK_INTERVAL_MS as e,DEFAULT_CORRELATION_ID_HEADER as t,DEFAULT_LOG_LEVEL as n,DEFAULT_RETRIES as r,DEFAULT_TIMEOUT_MS as i,DEFAULT_VERSION_URL as a,getConfig as o,getConfigValue as s,resetConfig as c,setConfig as l}from"./config/index.js";import{Logger as u,configureLogger as d,getDeviceContext as f,setDeviceContext as p,setRemoteLogger as m}from"./logger/logger.js";import{decodeJWT as h,getJWTExpiry as g,isJWTExpired as _}from"./auth/jwt.js";import{ACCESS_TOKEN_KEY as v,LEGACY_REFRESH_TOKEN_LIFETIME_MS as y,REFRESH_TOKEN_KEY as b,SESSION_USER_KEY as x,addSessionEndedListener as S,clearSession as C,getKeepSignedIn as w,getSessionUser as T,getToken as E,hasSession as D,hasSessionEndedInTab as O,removeSessionUser as k,removeToken as A,setKeepSignedIn as j,setLegacyTokenKeys as M,storeSessionUser as N,storeToken as P}from"./auth/authStore.js";import{addNetworkStatusListener as F,getNetworkStatus as I,setNetworkStatusImplementation as L,useNetworkStatus as R}from"./network/networkStatus.js";import{ACCOUNT_ID_HEADER as z,CLIENT_BUILD_HEADER as B,CLIENT_KIND as V,CLIENT_KIND_HEADER as H,getClientBuild as U}from"./api/clientHeaders.js";import{DESIGN_SAMPLE_HEADER as W,DESIGN_SAMPLE_QUERY_KEY as G,DESIGN_SAMPLE_STORAGE_KEY as K,applyDesignSample as q,readDesignSampleTicket as J}from"./api/designSample.js";import{MIN_APP_VERSION_HEADER as Y,addMinAppVersionListener as X,getMinAppVersion as Z}from"./api/minAppVersion.js";import{applyRequestDefaults as Q,newCorrelationId as $}from"./api/requestDefaults.js";import{WORKSPACE_CHANGED_CODE as ee,WorkspaceChangedError as te,isWorkspaceChangedError as ne}from"./api/workspaceChanged.js";import{IDEMPOTENCY_KEY_HEADER as re,attachRetry as ie,isNeverSentError as ae,isRetryableFailure as oe,isRetryableStatus as se,retryAfterMs as ce}from"./api/retry.js";import{REFRESH_LOCK_NAME as le,withCrossTabRefreshLock as ue}from"./api/crossTabRefreshLock.js";import de from"./api/publicClient.js";import{SIGN_OUT_REASON_HEADER as fe,injectStore as pe,injectUserAuth as me,refreshAccessToken as he,resetRefreshState as ge}from"./api/tokenRefresh.js";import _e,{RequestOfflineError as ve,SESSION_TERMINATION_CODES as ye}from"./api/userClient.js";import{initUserAuth as be}from"./initUserAuth.js";import{CONTRACT_ERROR_CODE as xe,NETWORK_CODE as Se,OFFLINE_CODE as Ce,OFFLINE_MESSAGE as we,REQUEST_CANCELED_CODE as Te,SERVER_FAILURE_MESSAGE as Ee,TIMEOUT_CODE as De,TIMEOUT_MESSAGE as Oe,UNEXPECTED_MESSAGE as ke,UNREACHABLE_MESSAGE as Ae,apiErrorMessage as je,extractApiError as Me,isApiError as Ne,isNoResponse as Pe,toFieldPath as Fe}from"./errors/extractApiError.js";import{configureFormatters as Ie,getFormatterConfig as Le}from"./formatters/formatConfig.js";import{formatCurrency as Re}from"./formatters/currency.js";import{addDays as ze}from"./formatters/dateMath.js";import{formatDate as Be,formatDateTime as Ve,formatMinor as He,formatNumber as Ue,formatPercent as We,formatRelative as Ge,formatTime as Ke}from"./formatters/house.js";import{initWebority as qe}from"./initSDK.js";import{createApiBaseQuery as Je}from"./query/apiBaseQuery.js";import{APP_API_DEFAULTS as Ye,createAppApi as Xe}from"./query/createAppApi.js";import{setupApiListeners as Ze}from"./query/listeners.js";import{buildListQuery as Qe,getNextPageParam as $e,getPreviousPageParam as et,hasNextPage as tt,hasPreviousPage as nt}from"./query/paging.js";import{LIST_TAG_ID as rt,itemTag as it,listTag as at,providesList as ot,providesPagedList as st}from"./query/tags.js";import{errorToastMiddleware as ct,isSilentRejection as lt}from"./redux/errorToastMiddleware.js";import{createRootReducer as ut,resetState as dt}from"./redux/rootReducer.js";import{SERIALIZABLE_IGNORED_ACTION_PATHS as ft}from"./redux/serializableCheck.js";import{hasRecentlyReloaded as pt,importWithReload as mt,isChunkLoadError as ht,lazyWithReload as gt,markReloaded as _t}from"./router/chunkReload.js";import{hasPermission as vt}from"./router/permissions.js";import{RETURN_TO_PARAM as yt,buildLoginPath as bt,getReturnTo as xt,toSafeReturnTo as St}from"./router/returnTo.js";import{PublicOnly as Ct,RequireAuth as wt,RequirePermission as Tt}from"./router/guards.js";import{publicOnly as Et,requireAuth as Dt,requirePermission as Ot,withGuards as kt}from"./router/loaders.js";import{classifyRouteError as At,useRouteErrorReport as jt}from"./router/routeError.js";import{staticUrl as Mt}from"./static/index.js";import{Storage as Nt,isStorageAvailable as Pt,setStorageImplementation as Ft,syncStorage as It}from"./storage/index.js";import{isBuildBelowMinimum as Lt,parseBuildNumber as Rt}from"./versionCheck/buildNumber.js";import{addDeployedBuildListener as zt,getNewerDeployedBuild as Bt,startDeployedBuildCheck as Vt}from"./versionCheck/deployedBuild.js";import{installReloadOnNavigate as Ht,isUpdateAvailable as Ut,useVersionCheck as Wt}from"./versionCheck/index.js";export{v as ACCESS_TOKEN_KEY,z as ACCOUNT_ID_HEADER,Ye as APP_API_DEFAULTS,B as CLIENT_BUILD_HEADER,V as CLIENT_KIND,H as CLIENT_KIND_HEADER,xe as CONTRACT_ERROR_CODE,e as DEFAULT_BUILD_CHECK_INTERVAL_MS,t as DEFAULT_CORRELATION_ID_HEADER,n as DEFAULT_LOG_LEVEL,r as DEFAULT_RETRIES,i as DEFAULT_TIMEOUT_MS,a as DEFAULT_VERSION_URL,W as DESIGN_SAMPLE_HEADER,G as DESIGN_SAMPLE_QUERY_KEY,K as DESIGN_SAMPLE_STORAGE_KEY,re as IDEMPOTENCY_KEY_HEADER,y as LEGACY_REFRESH_TOKEN_LIFETIME_MS,rt as LIST_TAG_ID,u as Logger,Y as MIN_APP_VERSION_HEADER,Se as NETWORK_CODE,Ce as OFFLINE_CODE,we as OFFLINE_MESSAGE,Ct as PublicOnly,le as REFRESH_LOCK_NAME,b as REFRESH_TOKEN_KEY,Te as REQUEST_CANCELED_CODE,yt as RETURN_TO_PARAM,ve as RequestOfflineError,wt as RequireAuth,Tt as RequirePermission,ft as SERIALIZABLE_IGNORED_ACTION_PATHS,Ee as SERVER_FAILURE_MESSAGE,ye as SESSION_TERMINATION_CODES,x as SESSION_USER_KEY,fe as SIGN_OUT_REASON_HEADER,Nt as Storage,De as TIMEOUT_CODE,Oe as TIMEOUT_MESSAGE,ke as UNEXPECTED_MESSAGE,Ae as UNREACHABLE_MESSAGE,ee as WORKSPACE_CHANGED_CODE,te as WorkspaceChangedError,ze as addDays,zt as addDeployedBuildListener,X as addMinAppVersionListener,F as addNetworkStatusListener,S as addSessionEndedListener,je as apiErrorMessage,q as applyDesignSample,Q as applyRequestDefaults,ie as attachRetry,Qe as buildListQuery,bt as buildLoginPath,At as classifyRouteError,C as clearSession,Ie as configureFormatters,d as configureLogger,Je as createApiBaseQuery,Xe as createAppApi,ut as createRootReducer,h as decodeJWT,ct as errorToastMiddleware,Me as extractApiError,Re as formatCurrency,Be as formatDate,Ve as formatDateTime,He as formatMinor,Ue as formatNumber,We as formatPercent,Ge as formatRelative,Ke as formatTime,U as getClientBuild,o as getConfig,s as getConfigValue,f as getDeviceContext,Le as getFormatterConfig,g as getJWTExpiry,w as getKeepSignedIn,Z as getMinAppVersion,I as getNetworkStatus,Bt as getNewerDeployedBuild,$e as getNextPageParam,et as getPreviousPageParam,xt as getReturnTo,T as getSessionUser,E as getToken,tt as hasNextPage,vt as hasPermission,nt as hasPreviousPage,pt as hasRecentlyReloaded,D as hasSession,O as hasSessionEndedInTab,mt as importWithReload,be as initUserAuth,qe as initWebority,pe as injectStore,me as injectUserAuth,Ht as installReloadOnNavigate,Ne as isApiError,Lt as isBuildBelowMinimum,ht as isChunkLoadError,_ as isJWTExpired,ae as isNeverSentError,Pe as isNoResponse,oe as isRetryableFailure,se as isRetryableStatus,lt as isSilentRejection,Pt as isStorageAvailable,Ut as isUpdateAvailable,ne as isWorkspaceChangedError,it as itemTag,gt as lazyWithReload,at as listTag,_t as markReloaded,$ as newCorrelationId,Rt as parseBuildNumber,ot as providesList,st as providesPagedList,de as publicClient,Et as publicOnly,J as readDesignSampleTicket,he as refreshAccessToken,k as removeSessionUser,A as removeToken,Dt as requireAuth,Ot as requirePermission,c as resetConfig,ge as resetRefreshState,dt as resetState,ce as retryAfterMs,l as setConfig,p as setDeviceContext,j as setKeepSignedIn,M as setLegacyTokenKeys,L as setNetworkStatusImplementation,m as setRemoteLogger,Ft as setStorageImplementation,Ze as setupApiListeners,Vt as startDeployedBuildCheck,Mt as staticUrl,N as storeSessionUser,P as storeToken,It as syncStorage,Fe as toFieldPath,St as toSafeReturnTo,R as useNetworkStatus,jt as useRouteErrorReport,Wt as useVersionCheck,_e as userClient,ue as withCrossTabRefreshLock,kt as withGuards};
@@ -0,0 +1,14 @@
1
+ import type { AxiosInstance } from "axios";
2
+ /** The page address key a compare or a person opens a staging page with. */
3
+ export declare const DESIGN_SAMPLE_QUERY_KEY = "designSample";
4
+ /** The request header that carries the ticket to the product's API; the API's Webority.Delivery reads it. */
5
+ export declare const DESIGN_SAMPLE_HEADER = "X-Design-Sample";
6
+ /** sessionStorage key: the ticket outlives in-app navigation and redirects, and ends with the tab. */
7
+ export declare const DESIGN_SAMPLE_STORAGE_KEY = "webority.designSample";
8
+ /**
9
+ * The ticket this tab was opened with, or null. Never reads anything when the configured environment is Production.
10
+ * The first call copies a ticket from the page address into sessionStorage.
11
+ */
12
+ export declare const readDesignSampleTicket: () => string | null;
13
+ /** Sends the ticket on every request of the client, unless the request already carries the header. */
14
+ export declare const applyDesignSample: (client: AxiosInstance) => void;
@@ -3,6 +3,7 @@ export { initUserAuth } from "../initUserAuth";
3
3
  export type { AccountIdProvider, ClientKind } from "./clientHeaders";
4
4
  export { ACCOUNT_ID_HEADER, CLIENT_BUILD_HEADER, CLIENT_KIND, CLIENT_KIND_HEADER, getClientBuild, } from "./clientHeaders";
5
5
  export { REFRESH_LOCK_NAME, withCrossTabRefreshLock } from "./crossTabRefreshLock";
6
+ export { applyDesignSample, DESIGN_SAMPLE_HEADER, DESIGN_SAMPLE_QUERY_KEY, DESIGN_SAMPLE_STORAGE_KEY, readDesignSampleTicket, } from "./designSample";
6
7
  export type { MinAppVersionListener } from "./minAppVersion";
7
8
  export { addMinAppVersionListener, getMinAppVersion, MIN_APP_VERSION_HEADER } from "./minAppVersion";
8
9
  export { default as publicClient } from "./publicClient";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webority/web-core",
3
- "version": "0.84.0",
3
+ "version": "0.85.0",
4
4
  "description": "Platform layer for Webority React web portals: HTTP clients with single-flight token refresh, auth store, API error extraction, RTK Query base query, logger, formatters, storage, version check and route guards. No UI.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",