@webority/mobile-core 0.92.0 → 0.93.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 (56) hide show
  1. package/README.md +11 -5
  2. package/lib/commonjs/api/clientHeaders.js +1 -1
  3. package/lib/commonjs/api/minAppVersion.js +1 -1
  4. package/lib/commonjs/api/requestDefaults.js +1 -1
  5. package/lib/commonjs/api/retry.js +1 -1
  6. package/lib/commonjs/api/tokenRefresh.js +1 -1
  7. package/lib/commonjs/api/userClient.js +1 -1
  8. package/lib/commonjs/api/workspace.js +1 -1
  9. package/lib/commonjs/auth/authStore.js +1 -1
  10. package/lib/commonjs/config/index.js +1 -1
  11. package/lib/commonjs/errors/extractApiError.js +1 -1
  12. package/lib/commonjs/index.js +1 -1
  13. package/lib/commonjs/initSDK.js +1 -1
  14. package/lib/commonjs/logger/index.js +1 -1
  15. package/lib/module/api/clientHeaders.js +1 -1
  16. package/lib/module/api/minAppVersion.js +1 -1
  17. package/lib/module/api/requestDefaults.js +1 -1
  18. package/lib/module/api/retry.js +1 -1
  19. package/lib/module/api/tokenRefresh.js +1 -1
  20. package/lib/module/api/userClient.js +1 -1
  21. package/lib/module/api/workspace.js +1 -1
  22. package/lib/module/auth/authStore.js +1 -1
  23. package/lib/module/config/index.js +1 -1
  24. package/lib/module/errors/extractApiError.js +1 -1
  25. package/lib/module/index.js +1 -1
  26. package/lib/module/initSDK.js +1 -1
  27. package/lib/module/logger/index.js +1 -1
  28. package/lib/typescript/commonjs/api/clientHeaders.d.ts +7 -7
  29. package/lib/typescript/commonjs/api/minAppVersion.d.ts +2 -3
  30. package/lib/typescript/commonjs/api/requestDefaults.d.ts +10 -7
  31. package/lib/typescript/commonjs/api/retry.d.ts +3 -3
  32. package/lib/typescript/commonjs/api/tokenRefresh.d.ts +8 -5
  33. package/lib/typescript/commonjs/api/userClient.d.ts +1 -23
  34. package/lib/typescript/commonjs/auth/authStore.d.ts +3 -6
  35. package/lib/typescript/commonjs/config/index.d.ts +2 -9
  36. package/lib/typescript/commonjs/errors/extractApiError.d.ts +7 -13
  37. package/lib/typescript/commonjs/index.d.ts +3 -3
  38. package/lib/typescript/commonjs/initSDK.d.ts +2 -4
  39. package/lib/typescript/commonjs/initUserAuth.d.ts +1 -8
  40. package/lib/typescript/commonjs/versionCheck/buildNumber.d.ts +1 -1
  41. package/lib/typescript/commonjs/versionCheck/index.d.ts +4 -4
  42. package/lib/typescript/module/api/clientHeaders.d.ts +7 -7
  43. package/lib/typescript/module/api/minAppVersion.d.ts +2 -3
  44. package/lib/typescript/module/api/requestDefaults.d.ts +10 -7
  45. package/lib/typescript/module/api/retry.d.ts +3 -3
  46. package/lib/typescript/module/api/tokenRefresh.d.ts +8 -5
  47. package/lib/typescript/module/api/userClient.d.ts +1 -23
  48. package/lib/typescript/module/auth/authStore.d.ts +3 -6
  49. package/lib/typescript/module/config/index.d.ts +2 -9
  50. package/lib/typescript/module/errors/extractApiError.d.ts +7 -13
  51. package/lib/typescript/module/index.d.ts +3 -3
  52. package/lib/typescript/module/initSDK.d.ts +2 -4
  53. package/lib/typescript/module/initUserAuth.d.ts +1 -8
  54. package/lib/typescript/module/versionCheck/buildNumber.d.ts +1 -1
  55. package/lib/typescript/module/versionCheck/index.d.ts +4 -4
  56. package/package.json +1 -1
@@ -1 +1 @@
1
- "use strict";export const SERVER_FAILURE_MESSAGE="Something went wrong on our side. Please try again in a moment.";export const OFFLINE_MESSAGE="You appear to be offline. Check your connection and try again.";export const TIMEOUT_MESSAGE="That took too long to respond. Check your connection and try again.";export const UNEXPECTED_MESSAGE="Something went wrong. Please try again.";export const UNREACHABLE_MESSAGE="We couldn't reach the server. Check your connection and try again.";export const REQUEST_CANCELED_CODE="request_canceled";export const CONTRACT_ERROR_CODE="contract_error";export const TIMEOUT_CODE="timeout";export const NETWORK_CODE="network";export const OFFLINE_CODE="offline";const INTERNAL_ERROR_CODE="internal_error",MAX_MESSAGE_LENGTH=300,requestFailedMessage=e=>`Request failed (${e})`,isDict=e=>"object"==typeof e&&null!==e&&!Array.isArray(e),nonEmptyString=e=>"string"==typeof e&&e.trim().length>0?e:null,looksLikeDiagnostics=e=>e.length>300||/^\s*</.test(e)||e.includes("\n at ")||/(Exception|StackTrace):/.test(e)||/\b(System|Microsoft)\.[A-Za-z]+\.[A-Za-z]/.test(e),userSafe=e=>{const t=nonEmptyString(e);return null===t||looksLikeDiagnostics(t)?null:t};export const toFieldPath=e=>e.replace(/^\$\.?/,"").split(".").map(e=>e.charAt(0).toLowerCase()+e.slice(1)).join(".");const firstMessage=e=>{if(Array.isArray(e)){for(const t of e){const e=nonEmptyString(t);if(null!==e)return e}return null}return nonEmptyString(e)},addError=(e,t,r)=>{const n=toFieldPath(t);""===n?e.form??=r:n in e.fields||(e.fields[n]=r)},readErrors=e=>{const t={fields:{},form:null};if(Array.isArray(e)){for(const r of e){if(!isDict(r))continue;const e=nonEmptyString(r.message);null!==e&&addError(t,"string"==typeof r.field?r.field:"",e)}return t}if(!isDict(e))return t;for(const[r,n]of Object.entries(e)){const e=firstMessage(n);null!==e&&addError(t,r,e)}return t},readLegacyError=e=>{const t=e.error;return isDict(t)?nonEmptyString(t.message):nonEmptyString(t)};export const isApiError=e=>isDict(e)&&"string"==typeof e.message&&"number"==typeof e.status&&"boolean"==typeof e.offline&&isDict(e.fieldErrors);const build=e=>({code:null,fieldErrors:{},status:0,offline:!1,traceId:null,detail:null,...e}),fromNoResponse=e=>{const t=nonEmptyString(e.code),r=nonEmptyString(e.name),n=nonEmptyString(e.message);return build("CanceledError"===r||"ERR_CANCELED"===t?{code:"request_canceled",message:UNEXPECTED_MESSAGE,detail:n}:"ECONNABORTED"===t||"ETIMEDOUT"===t?{code:"timeout",message:TIMEOUT_MESSAGE,offline:!0,detail:n}:"RequestOfflineError"===r?{code:"offline",message:OFFLINE_MESSAGE,offline:!0,detail:n}:"ERR_NETWORK"===t||"Network Error"===n||"Network request failed"===n?{code:"network",message:UNREACHABLE_MESSAGE,offline:!0,detail:n}:{message:UNEXPECTED_MESSAGE,detail:n})};export function extractApiError(e){if(isApiError(e))return e;if("string"==typeof e)return build({message:userSafe(e)??UNEXPECTED_MESSAGE,detail:e||null});if(!isDict(e))return build({message:UNEXPECTED_MESSAGE,detail:null==e?null:String(e)});if(!0===e.isContractError)return build({code:"contract_error",message:userSafe(e.message)??UNEXPECTED_MESSAGE,detail:nonEmptyString(e.message)});const t=isDict(e.response)?e.response:null,r="number"==typeof t?.status?t.status:"number"==typeof e.status?e.status:0,n=t?t.data:e.body;if(0===r&&null==n)return fromNoResponse(e);const o=isDict(n)?n:null,{fields:s,form:i}=readErrors(o?.errors),E=nonEmptyString(o?.code),a=nonEmptyString(o?.traceId),l=nonEmptyString(o?.message)??nonEmptyString(o?.detail)??(o?readLegacyError(o):null)??nonEmptyString(o?.title)??nonEmptyString(n)??nonEmptyString(e.message);let c;if(r>=500){c=(null!==E&&"internal_error"!==E?userSafe(o?.message):null)??SERVER_FAILURE_MESSAGE}else c=userSafe(Object.values(s)[0])??userSafe(i)??userSafe(o?.message)??userSafe(o?.detail)??(o?userSafe(readLegacyError(o)):null)??userSafe(o?.title)??userSafe(n)??(r?requestFailedMessage(r):UNEXPECTED_MESSAGE);return build({code:E,message:c,fieldErrors:s,status:r,traceId:a,detail:l})}export const isNoResponse=e=>extractApiError(e).offline;export function apiErrorMessage(e,t){const r=extractApiError(e);if(r.offline||null!==t&&!t)return r.message;return r.message===SERVER_FAILURE_MESSAGE||"request_canceled"===r.code||r.message===UNEXPECTED_MESSAGE||r.message===requestFailedMessage(r.status)?t??null:r.message}
1
+ "use strict";export const SERVER_FAILURE_MESSAGE="Something went wrong on our side. Please try again in a moment.";export const OFFLINE_MESSAGE="You appear to be offline. Check your connection and try again.";export const TIMEOUT_MESSAGE="That took too long to respond. Check your connection and try again.";export const UNEXPECTED_MESSAGE="Something went wrong. Please try again.";export const UNREACHABLE_MESSAGE="We couldn't reach the server. Check your connection and try again.";export const REQUEST_CANCELED_CODE="request_canceled";export const CONTRACT_ERROR_CODE="contract_error";export const TIMEOUT_CODE="timeout";export const NETWORK_CODE="network";export const OFFLINE_CODE="offline";const INTERNAL_ERROR_CODE="internal_error",MAX_MESSAGE_LENGTH=300,requestFailedMessage=e=>`Request failed (${e})`,isDict=e=>"object"==typeof e&&null!==e&&!Array.isArray(e),nonEmptyString=e=>"string"==typeof e&&e.trim().length>0?e:null,looksLikeDiagnostics=e=>e.length>300||/^\s*</.test(e)||e.includes("\n at ")||/(Exception|StackTrace):/.test(e)||/\b(System|Microsoft)\.[A-Za-z]+\.[A-Za-z]/.test(e),userSafe=e=>{const t=nonEmptyString(e);return null===t||looksLikeDiagnostics(t)?null:t};export const toFieldPath=e=>e.replace(/^\$\.?/,"").split(".").map(e=>e.charAt(0).toLowerCase()+e.slice(1)).join(".");const firstMessage=e=>{if(Array.isArray(e)){for(const t of e){const e=nonEmptyString(t);if(null!==e)return e}return null}return nonEmptyString(e)},addError=(e,t,r)=>{const n=toFieldPath(t);""===n?e.form??=r:n in e.fields||(e.fields[n]=r)},readErrors=e=>{const t={fields:{},form:null};if(Array.isArray(e)){for(const r of e){if(!isDict(r))continue;const e=nonEmptyString(r.message);null!==e&&addError(t,"string"==typeof r.field?r.field:"",e)}return t}if(!isDict(e))return t;for(const[r,n]of Object.entries(e)){const e=firstMessage(n);null!==e&&addError(t,r,e)}return t};export const isApiError=e=>isDict(e)&&"string"==typeof e.message&&"number"==typeof e.status&&"boolean"==typeof e.offline&&isDict(e.fieldErrors);const build=e=>({code:null,fieldErrors:{},status:0,offline:!1,traceId:null,diagnostic:null,...e}),requestTraceId=e=>{const t=isDict(e.config)?e.config.headers:void 0;if(!isDict(t))return null;const r="function"==typeof t.get?t.get("traceparent"):t.traceparent??t.Traceparent,n="string"==typeof r?/^00-([0-9a-f]{32})-[0-9a-f]{16}-[0-9a-f]{2}$/.exec(r):null;return n?n[1]:null},fromNoResponse=e=>{const t=nonEmptyString(e.code),r=nonEmptyString(e.name),n=nonEmptyString(e.message),o=requestTraceId(e);return build("CanceledError"===r||"ERR_CANCELED"===t?{code:"request_canceled",message:UNEXPECTED_MESSAGE,traceId:o,diagnostic:n}:"ECONNABORTED"===t||"ETIMEDOUT"===t?{code:"timeout",message:TIMEOUT_MESSAGE,offline:!0,traceId:o,diagnostic:n}:"RequestOfflineError"===r?{code:"offline",message:OFFLINE_MESSAGE,offline:!0,traceId:o,diagnostic:n}:"ERR_NETWORK"===t||"Network Error"===n||"Network request failed"===n?{code:"network",message:UNREACHABLE_MESSAGE,offline:!0,traceId:o,diagnostic:n}:{message:UNEXPECTED_MESSAGE,traceId:o,diagnostic:n})};export function extractApiError(e){if(isApiError(e))return e;if("string"==typeof e)return build({message:userSafe(e)??UNEXPECTED_MESSAGE,diagnostic:e||null});if(!isDict(e))return build({message:UNEXPECTED_MESSAGE,diagnostic:null==e?null:String(e)});if(!0===e.isContractError)return build({code:"contract_error",message:userSafe(e.message)??UNEXPECTED_MESSAGE,diagnostic:nonEmptyString(e.message)});const t=isDict(e.response)?e.response:null,r="number"==typeof t?.status?t.status:"number"==typeof e.status?e.status:0,n=t?t.data:e.body;if(0===r&&null==n)return fromNoResponse(e);const o=isDict(n)?n:null,{fields:s,form:i}=readErrors(o?.errors),a=nonEmptyString(o?.code),E=nonEmptyString(o?.traceId)??requestTraceId(e),c=nonEmptyString(o?.detail)??nonEmptyString(o?.title)??nonEmptyString(n)??nonEmptyString(e.message);let l;if(r>=500){l=(null!==a&&"internal_error"!==a?userSafe(o?.detail):null)??SERVER_FAILURE_MESSAGE}else l=userSafe(Object.values(s)[0])??userSafe(i)??userSafe(o?.detail)??userSafe(o?.title)??userSafe(n)??(r?requestFailedMessage(r):UNEXPECTED_MESSAGE);return build({code:a,message:l,fieldErrors:s,status:r,traceId:E,diagnostic:c})}export const isNoResponse=e=>extractApiError(e).offline;export function apiErrorMessage(e,t){const r=extractApiError(e);if(r.offline||null!==t&&!t)return r.message;return r.message===SERVER_FAILURE_MESSAGE||"request_canceled"===r.code||r.message===UNEXPECTED_MESSAGE||r.message===requestFailedMessage(r.status)?t??null:r.message}
@@ -1 +1 @@
1
- "use strict";export{ACCOUNT_ID_HEADER,CLIENT_BUILD_HEADER,CLIENT_KIND,CLIENT_KIND_HEADER,getClientBuild}from"./api/clientHeaders.js";export{buildCurl,logCurl}from"./api/curl.js";export{addMinAppVersionListener,getMinAppVersion,MIN_APP_VERSION_HEADER}from"./api/minAppVersion.js";export{default as publicClient}from"./api/publicClient.js";export{applyRequestDefaults,newCorrelationId}from"./api/requestDefaults.js";export{attachRetry,IDEMPOTENCY_KEY_HEADER,isNeverSentError,isRetryableFailure,isRetryableStatus,retryAfterMs}from"./api/retry.js";export{refreshAccessToken}from"./api/tokenRefresh.js";export{default as userClient,injectStore,injectUserAuth,RequestOfflineError,resetRefreshState,SESSION_TERMINATION_CODES,SIGN_OUT_REASON_HEADER}from"./api/userClient.js";export{isWorkspaceChangedError,WORKSPACE_CHANGED_CODE,WorkspaceChangedError}from"./api/workspace.js";export{ACCESS_TOKEN_KEY,addSessionEndedListener,clearSession,getSessionUser,getToken,LEGACY_REFRESH_TOKEN_LIFETIME_MS,REFRESH_TOKEN_KEY,removeSessionUser,removeToken,SESSION_USER_KEY,setKeychainImplementation,setLegacyTokenKeys,storeSessionUser,storeToken}from"./auth/authStore.js";export{decodeJWT,getJWTExpiry,isJWTExpired}from"./auth/jwt.js";export{getConfig,getConfigValue,resetConfig,setConfig}from"./config/index.js";export{DeepLink,parseDeepLink,useDeepLink}from"./deepLink/index.js";export{apiErrorMessage,CONTRACT_ERROR_CODE,extractApiError,isApiError,isNoResponse,NETWORK_CODE,OFFLINE_CODE,OFFLINE_MESSAGE,REQUEST_CANCELED_CODE,SERVER_FAILURE_MESSAGE,TIMEOUT_CODE,TIMEOUT_MESSAGE,toFieldPath,UNEXPECTED_MESSAGE,UNREACHABLE_MESSAGE}from"./errors/index.js";export{AsYouType,addDays,clampNationalNumber,configureFormatters,countryFlagEmoji,detectPhoneCountry,diffMs,formatCompactNumber,formatCurrency,formatDate,formatDateDDMMMYYYY,formatDateISO,formatDatePattern,formatDateTime,formatMinor,formatNumber,formatPercent,formatPhone,formatPhoneAsTyped,formatRelative,formatRelativeTime,formatTime,formatTime12h,formatTimeInWindowsZone,formatTimeInZone,getCountries,getCountryCallingCode,getFormatterConfig,getInitials,getPhoneCountries,isDateAfter,isDateBefore,isSameDay,isSupportedCountry,isValidNationalNumber,isValidPhoneNumber,maxNationalNumberLength,normalizePhone,parsePhoneNumber,parsePhoneNumberFromString,splitPhoneNumber,startOfDay,validatePhoneNumberLength}from"./formatters/index.js";export{initWebority}from"./initSDK.js";export{initUserAuth}from"./initUserAuth.js";export{configureLogger,getDeviceContext,Logger,setDeviceContext}from"./logger/index.js";export{crashlyticsRemoteLogger}from"./logger/crashlytics.js";export{addNetworkStatusListener,getNetworkStatus,setNetworkStatusImplementation,useNetworkStatus}from"./network/index.js";export{PUSH_STATUS}from"./push/status.js";export{isStorageAvailable,Storage,setStorageImplementation}from"./storage/index.js";export{encodeBase64}from"./utils/base64.js";export{isAadhaar,isAlphanumeric,isBetween,isEmail,isGstin,isHexColor,isIfsc,isIndianMobile,isIndianPincode,isInteger,isNonEmpty,isNumeric,isPan,isPhone,isStrongPassword,isUrl,maxLength,minLength}from"./validators/index.js";export{isBuildBelowMinimum,parseBuildNumber,setDeviceInfoImplementation,useVersionCheck,VersionCheck}from"./versionCheck/index.js";
1
+ "use strict";export{ACCOUNT_ID_HEADER,CLIENT_BUILD_HEADER,CLIENT_KIND,CLIENT_KIND_HEADER,getClientBuild}from"./api/clientHeaders.js";export{buildCurl,logCurl}from"./api/curl.js";export{addMinAppVersionListener,getMinAppVersion,MIN_APP_VERSION_HEADER}from"./api/minAppVersion.js";export{default as publicClient}from"./api/publicClient.js";export{applyRequestDefaults,newTraceparent,TRACEPARENT_HEADER}from"./api/requestDefaults.js";export{attachRetry,IDEMPOTENCY_KEY_HEADER,isNeverSentError,isRetryableFailure,isRetryableStatus,retryAfterMs}from"./api/retry.js";export{refreshAccessToken}from"./api/tokenRefresh.js";export{default as userClient,injectStore,injectUserAuth,RequestOfflineError,resetRefreshState,SESSION_EXPIRED_CODE,SESSION_REVOKED_CODE}from"./api/userClient.js";export{isWorkspaceChangedError,WORKSPACE_CHANGED_CODE,WorkspaceChangedError}from"./api/workspace.js";export{ACCESS_TOKEN_KEY,addSessionEndedListener,clearSession,getSessionUser,getToken,LEGACY_REFRESH_TOKEN_LIFETIME_MS,REFRESH_TOKEN_KEY,removeSessionUser,removeToken,SESSION_USER_KEY,setKeychainImplementation,setLegacyTokenKeys,storeSessionUser,storeToken}from"./auth/authStore.js";export{decodeJWT,getJWTExpiry,isJWTExpired}from"./auth/jwt.js";export{getConfig,getConfigValue,resetConfig,setConfig}from"./config/index.js";export{DeepLink,parseDeepLink,useDeepLink}from"./deepLink/index.js";export{apiErrorMessage,CONTRACT_ERROR_CODE,extractApiError,isApiError,isNoResponse,NETWORK_CODE,OFFLINE_CODE,OFFLINE_MESSAGE,REQUEST_CANCELED_CODE,SERVER_FAILURE_MESSAGE,TIMEOUT_CODE,TIMEOUT_MESSAGE,toFieldPath,UNEXPECTED_MESSAGE,UNREACHABLE_MESSAGE}from"./errors/index.js";export{AsYouType,addDays,clampNationalNumber,configureFormatters,countryFlagEmoji,detectPhoneCountry,diffMs,formatCompactNumber,formatCurrency,formatDate,formatDateDDMMMYYYY,formatDateISO,formatDatePattern,formatDateTime,formatMinor,formatNumber,formatPercent,formatPhone,formatPhoneAsTyped,formatRelative,formatRelativeTime,formatTime,formatTime12h,formatTimeInWindowsZone,formatTimeInZone,getCountries,getCountryCallingCode,getFormatterConfig,getInitials,getPhoneCountries,isDateAfter,isDateBefore,isSameDay,isSupportedCountry,isValidNationalNumber,isValidPhoneNumber,maxNationalNumberLength,normalizePhone,parsePhoneNumber,parsePhoneNumberFromString,splitPhoneNumber,startOfDay,validatePhoneNumberLength}from"./formatters/index.js";export{initWebority}from"./initSDK.js";export{initUserAuth}from"./initUserAuth.js";export{configureLogger,getDeviceContext,Logger,setDeviceContext}from"./logger/index.js";export{crashlyticsRemoteLogger}from"./logger/crashlytics.js";export{addNetworkStatusListener,getNetworkStatus,setNetworkStatusImplementation,useNetworkStatus}from"./network/index.js";export{PUSH_STATUS}from"./push/status.js";export{isStorageAvailable,Storage,setStorageImplementation}from"./storage/index.js";export{encodeBase64}from"./utils/base64.js";export{isAadhaar,isAlphanumeric,isBetween,isEmail,isGstin,isHexColor,isIfsc,isIndianMobile,isIndianPincode,isInteger,isNonEmpty,isNumeric,isPan,isPhone,isStrongPassword,isUrl,maxLength,minLength}from"./validators/index.js";export{isBuildBelowMinimum,parseBuildNumber,setDeviceInfoImplementation,useVersionCheck,VersionCheck}from"./versionCheck/index.js";
@@ -1 +1 @@
1
- "use strict";import{setKeychainImplementation}from"./auth/authStore.js";import{DEFAULT_CORRELATION_ID_HEADER,DEFAULT_LOG_LEVEL,DEFAULT_RETRIES,DEFAULT_TIMEOUT_MS,setConfig}from"./config/index.js";import{Logger,setRemoteLogger}from"./logger/index.js";import{setNetworkStatusImplementation}from"./network/networkStatus.js";import{setStorageImplementation}from"./storage/index.js";export const initWebority=e=>{if(!e.baseUrl)throw new Error("baseUrl is required for Webority packages initialization");if(void 0===e.remoteLogger)throw new Error("remoteLogger is required for Webority packages initialization: pass a RemoteLogger, or null for a build without crash reporting");setRemoteLogger(e.remoteLogger),setConfig({baseUrl:e.baseUrl,loggingEnabled:e.loggingEnabled??!0,logLevel:e.logLevel||DEFAULT_LOG_LEVEL,environment:e.environment||"Development",country:(e.country||"in").toLowerCase(),appId:e.appId??null,appVersion:e.appVersion??null,commit:e.commit??null,appBuild:e.appBuild??null,appStoreId:e.appStoreId??null,logCurl:e.logCurl??!1,timeoutMs:e.timeoutMs??DEFAULT_TIMEOUT_MS,retries:e.retries??DEFAULT_RETRIES,correlationIdHeader:void 0===e.correlationIdHeader?DEFAULT_CORRELATION_ID_HEADER:e.correlationIdHeader});const o=e.backends;o?.storage&&setStorageImplementation(o.storage),o?.keychain&&setKeychainImplementation(o.keychain),o?.network&&setNetworkStatusImplementation(o.network),Logger.info("[@webority/mobile-core] initialized")};
1
+ "use strict";import{setKeychainImplementation}from"./auth/authStore.js";import{DEFAULT_LOG_LEVEL,DEFAULT_RETRIES,DEFAULT_TIMEOUT_MS,setConfig}from"./config/index.js";import{Logger,setRemoteLogger}from"./logger/index.js";import{setNetworkStatusImplementation}from"./network/networkStatus.js";import{setStorageImplementation}from"./storage/index.js";export const initWebority=e=>{if(!e.baseUrl)throw new Error("baseUrl is required for Webority packages initialization");if(void 0===e.remoteLogger)throw new Error("remoteLogger is required for Webority packages initialization: pass a RemoteLogger, or null for a build without crash reporting");setRemoteLogger(e.remoteLogger),setConfig({baseUrl:e.baseUrl,loggingEnabled:e.loggingEnabled??!0,logLevel:e.logLevel||DEFAULT_LOG_LEVEL,environment:e.environment||"Development",country:(e.country||"in").toLowerCase(),appId:e.appId??null,appVersion:e.appVersion??null,commit:e.commit??null,appBuild:e.appBuild??null,appStoreId:e.appStoreId??null,logCurl:e.logCurl??!1,timeoutMs:e.timeoutMs??DEFAULT_TIMEOUT_MS,retries:e.retries??DEFAULT_RETRIES});const o=e.backends;o?.storage&&setStorageImplementation(o.storage),o?.keychain&&setKeychainImplementation(o.keychain),o?.network&&setNetworkStatusImplementation(o.network),Logger.info("[@webority/mobile-core] initialized")};
@@ -1 +1 @@
1
- "use strict";import{getConfigValue}from"../config/index.js";import{isNoResponse}from"../errors/extractApiError.js";import{configureRedaction,redact,redactError,redactString}from"./redact.js";const Colors={RESET:"",GRAY:"",BLUE:"",YELLOW:"",RED_BOLD:""},LogLevels={DEBUG:{level:"debug",color:Colors.GRAY},INFO:{level:"info",color:Colors.BLUE},WARN:{level:"warn",color:Colors.YELLOW},ERROR:{level:"error",color:Colors.RED_BOLD}},levels=["debug","info","warn","error"],isLogLevelAllowed=e=>{const r=getConfigValue("logLevel","info");return levels.indexOf(e)>=levels.indexOf(r)},isEnabled=()=>getConfigValue("loggingEnabled",!0);let remote=null;export const setRemoteLogger=e=>{remote=e};const safe=e=>{if(e)try{e()}catch{}};let deviceContext=null;const normalizeAttributeValue=e=>null==e?null:"string"==typeof e||"number"==typeof e||"boolean"==typeof e?e:String(e);export const setDeviceContext=e=>{if(deviceContext=e,e)for(const[r,o]of Object.entries(e))safe(()=>remote?.setAttribute?.(r,normalizeAttributeValue(o)))};export const getDeviceContext=()=>deviceContext;const DEFAULT_LOGGER_OPTIONS={dedupeWindowMs:5e3,dedupeMaxPerWindow:1,screenHistoryLimit:20,breadcrumbLimit:50};let loggerOptions={...DEFAULT_LOGGER_OPTIONS};export const configureLogger=e=>{const{redactKeys:r,...o}=e;void 0!==r&&configureRedaction(r),loggerOptions={...loggerOptions,...o},screenHistory.length>loggerOptions.screenHistoryLimit&&(screenHistory=screenHistory.slice(screenHistory.length-loggerOptions.screenHistoryLimit)),trimBreadcrumbs()};let currentScreen=null,screenHistory=[];const breadcrumbs=[],trimBreadcrumbs=()=>{const e=breadcrumbs.length-loggerOptions.breadcrumbLimit;e>0&&breadcrumbs.splice(0,e)},dedupeMap=new Map,MAX_DEDUPE_ENTRIES=200,dedupeKeyFor=e=>{const r=e.stack?.split("\n")[1]?.trim();return r?`${e.message}::${r}`:e.message},capDedupeMap=()=>{for(;dedupeMap.size>200;){const e=dedupeMap.keys().next().value;if(void 0===e)return;dedupeMap.delete(e)}},shouldForward=e=>{if(loggerOptions.dedupeWindowMs<=0)return{forward:!0};const r=Date.now(),o=dedupeMap.get(e);if(!o||r-o.windowStart>=loggerOptions.dedupeWindowMs){const t=o?.suppressedCount??0;return dedupeMap.set(e,{windowStart:r,count:1,suppressedCount:0}),capDedupeMap(),t>0?{forward:!0,suppressedCount:t}:{forward:!0}}return o.count+=1,o.count>loggerOptions.dedupeMaxPerWindow?(o.suppressedCount+=1,{forward:!1}):{forward:!0}},buildErrorContext=(e,r)=>{const o={...deviceContext};return null!==currentScreen&&(o.screen=currentScreen),r&&(o.suppressedCount=r),{...o,...e}},forwardErrorToRemote=(e,r)=>{const o=dedupeKeyFor(e),{forward:t,suppressedCount:s}=shouldForward(o);t&&safe(()=>remote?.recordError?.(e,buildErrorContext(r,s)))},logDebug=(e,...r)=>{isEnabled()&&isLogLevelAllowed(LogLevels.DEBUG.level)&&console.debug(`${LogLevels.DEBUG.color}[DEBUG]: ${redactString(e)}${Colors.RESET}`,...redact(r))},logInfo=(e,...r)=>{if(!isEnabled()||!isLogLevelAllowed(LogLevels.INFO.level))return;const o=redactString(e),t=redact(r);console.info(`${LogLevels.INFO.color}[INFO]: ${o}${Colors.RESET}`,...t),safe(()=>remote?.log?.("info",o,t))},logWarning=(e,...r)=>{if(!isEnabled()||!isLogLevelAllowed(LogLevels.WARN.level))return;const o=redactString(e),t=redact(r);console.warn(`${LogLevels.WARN.color}[WARNING]: ${o}${Colors.RESET}`,...t),safe(()=>remote?.log?.("warn",o,t))},logError=(e,...r)=>{const o=redactString(e),t=redact(r);isEnabled()&&isLogLevelAllowed(LogLevels.ERROR.level)&&console.error(`${LogLevels.ERROR.color}[ERROR]: ${o}${Colors.RESET}`,...t),safe(()=>remote?.log?.("error",o,t));const s=r[0];void 0===s||isNoResponse(s)||forwardErrorToRemote(redactError(s),{source:"Logger.error",message:o})},breadcrumb=(e,r)=>{const o=redactString(e),t=redact(r);breadcrumbs.push({message:o,data:t,timestampUtc:(new Date).toISOString()}),trimBreadcrumbs(),isEnabled()&&isLogLevelAllowed("info")&&console.info(`${Colors.BLUE}[BREADCRUMB]: ${o}${Colors.RESET}`,t??""),safe(()=>remote?.breadcrumb?.(o,t))},recordError=(e,r)=>{const o=redactError(e),t=redact(r);isNoResponse(e)?logInfo(`No response: ${o.message}`):(isEnabled()&&isLogLevelAllowed("error")&&console.error(`${Colors.RED_BOLD}[RECORDED]: ${o.message}${Colors.RESET}`,t??""),forwardErrorToRemote(o,t))},asDict=e=>"object"==typeof e&&null!==e?e:null,headerValue=(e,r)=>{const o=asDict(e);if(!o)return null;const t="function"==typeof o.get?o.get.call(e,r):o[r]??o[r.toLowerCase()];return"string"==typeof t&&""!==t?t:null},requestFailed=(e,r={})=>{const{label:o,expectedStatuses:t=[],...s}=r,n=asDict(e),l=asDict(n?.config),c=asDict(n?.response),i=asDict(c?.data),a="number"==typeof c?.status?c.status:null,d="string"==typeof l?.method?l.method.toUpperCase():null,u="string"==typeof l?.url?l.url.split("?")[0]??null:null,g=o??([d,u].filter(Boolean).join(" ")||"Request");if("CanceledError"===n?.name||"ERR_CANCELED"===n?.code||!0===n?.__CANCEL__)return void logInfo(`${g} canceled`);if("RequestOfflineError"===n?.name)return void logInfo(`${g} not sent (offline)`);if(isNoResponse(e))return void logInfo(`${g} got no response`);if("WorkspaceChangedError"===n?.name||"workspace_changed"===i?.code)return void logInfo(`${g} refused (another workspace)`);if(null!==a&&t.includes(a))return void logInfo(`${g} refused (${a})`);const p="string"==typeof n?.message?n.message:e instanceof Error?e.message:null,f=redactString(null===a?`${g} failed`:`${g} failed (${a})`);isEnabled()&&isLogLevelAllowed(LogLevels.ERROR.level)&&console.error(`${LogLevels.ERROR.color}[ERROR]: ${f}${Colors.RESET}`,redactString(p??"")),safe(()=>remote?.log?.("error",f,[]));const E=getConfigValue("correlationIdHeader",null),m=redact({source:"Logger.requestFailed",label:g,status:a,method:d,path:u,code:"string"==typeof i?.code?i.code:null,traceId:"string"==typeof i?.traceId?i.traceId:null,correlationId:E?headerValue(l?.headers,E):null,detail:p,...s});forwardErrorToRemote(new Error(f),m)},setUser=(e,r)=>{safe(()=>remote?.setUser?.(e,r))},setAttribute=(e,r)=>{safe(()=>remote?.setAttribute?.(e,r))},trackScreen=(e,r)=>{e!==currentScreen&&(currentScreen=e,screenHistory.push(e),screenHistory.length>loggerOptions.screenHistoryLimit&&(screenHistory=screenHistory.slice(screenHistory.length-loggerOptions.screenHistoryLimit)),breadcrumb(`Screen: ${e}`,r))},getCurrentScreen=()=>currentScreen,getScreenHistory=()=>[...screenHistory],getBreadcrumbs=()=>[...breadcrumbs];export const Logger={debug:logDebug,info:logInfo,warn:logWarning,error:logError,breadcrumb:breadcrumb,recordError:recordError,requestFailed:requestFailed,setUser:setUser,setAttribute:setAttribute,trackScreen:trackScreen,getCurrentScreen:getCurrentScreen,getScreenHistory:getScreenHistory,getBreadcrumbs:getBreadcrumbs};
1
+ "use strict";import{TRACEPARENT_HEADER}from"../api/requestDefaults.js";import{getConfigValue}from"../config/index.js";import{isNoResponse}from"../errors/extractApiError.js";import{configureRedaction,redact,redactError,redactString}from"./redact.js";const Colors={RESET:"",GRAY:"",BLUE:"",YELLOW:"",RED_BOLD:""},LogLevels={DEBUG:{level:"debug",color:Colors.GRAY},INFO:{level:"info",color:Colors.BLUE},WARN:{level:"warn",color:Colors.YELLOW},ERROR:{level:"error",color:Colors.RED_BOLD}},levels=["debug","info","warn","error"],isLogLevelAllowed=e=>{const r=getConfigValue("logLevel","info");return levels.indexOf(e)>=levels.indexOf(r)},isEnabled=()=>getConfigValue("loggingEnabled",!0);let remote=null;export const setRemoteLogger=e=>{remote=e};const safe=e=>{if(e)try{e()}catch{}};let deviceContext=null;const normalizeAttributeValue=e=>null==e?null:"string"==typeof e||"number"==typeof e||"boolean"==typeof e?e:String(e);export const setDeviceContext=e=>{if(deviceContext=e,e)for(const[r,o]of Object.entries(e))safe(()=>remote?.setAttribute?.(r,normalizeAttributeValue(o)))};export const getDeviceContext=()=>deviceContext;const DEFAULT_LOGGER_OPTIONS={dedupeWindowMs:5e3,dedupeMaxPerWindow:1,screenHistoryLimit:20,breadcrumbLimit:50};let loggerOptions={...DEFAULT_LOGGER_OPTIONS};export const configureLogger=e=>{const{redactKeys:r,...o}=e;void 0!==r&&configureRedaction(r),loggerOptions={...loggerOptions,...o},screenHistory.length>loggerOptions.screenHistoryLimit&&(screenHistory=screenHistory.slice(screenHistory.length-loggerOptions.screenHistoryLimit)),trimBreadcrumbs()};let currentScreen=null,screenHistory=[];const breadcrumbs=[],trimBreadcrumbs=()=>{const e=breadcrumbs.length-loggerOptions.breadcrumbLimit;e>0&&breadcrumbs.splice(0,e)},dedupeMap=new Map,MAX_DEDUPE_ENTRIES=200,dedupeKeyFor=e=>{const r=e.stack?.split("\n")[1]?.trim();return r?`${e.message}::${r}`:e.message},capDedupeMap=()=>{for(;dedupeMap.size>200;){const e=dedupeMap.keys().next().value;if(void 0===e)return;dedupeMap.delete(e)}},shouldForward=e=>{if(loggerOptions.dedupeWindowMs<=0)return{forward:!0};const r=Date.now(),o=dedupeMap.get(e);if(!o||r-o.windowStart>=loggerOptions.dedupeWindowMs){const t=o?.suppressedCount??0;return dedupeMap.set(e,{windowStart:r,count:1,suppressedCount:0}),capDedupeMap(),t>0?{forward:!0,suppressedCount:t}:{forward:!0}}return o.count+=1,o.count>loggerOptions.dedupeMaxPerWindow?(o.suppressedCount+=1,{forward:!1}):{forward:!0}},buildErrorContext=(e,r)=>{const o={...deviceContext};return null!==currentScreen&&(o.screen=currentScreen),r&&(o.suppressedCount=r),{...o,...e}},forwardErrorToRemote=(e,r)=>{const o=dedupeKeyFor(e),{forward:t,suppressedCount:s}=shouldForward(o);t&&safe(()=>remote?.recordError?.(e,buildErrorContext(r,s)))},logDebug=(e,...r)=>{isEnabled()&&isLogLevelAllowed(LogLevels.DEBUG.level)&&console.debug(`${LogLevels.DEBUG.color}[DEBUG]: ${redactString(e)}${Colors.RESET}`,...redact(r))},logInfo=(e,...r)=>{if(!isEnabled()||!isLogLevelAllowed(LogLevels.INFO.level))return;const o=redactString(e),t=redact(r);console.info(`${LogLevels.INFO.color}[INFO]: ${o}${Colors.RESET}`,...t),safe(()=>remote?.log?.("info",o,t))},logWarning=(e,...r)=>{if(!isEnabled()||!isLogLevelAllowed(LogLevels.WARN.level))return;const o=redactString(e),t=redact(r);console.warn(`${LogLevels.WARN.color}[WARNING]: ${o}${Colors.RESET}`,...t),safe(()=>remote?.log?.("warn",o,t))},logError=(e,...r)=>{const o=redactString(e),t=redact(r);isEnabled()&&isLogLevelAllowed(LogLevels.ERROR.level)&&console.error(`${LogLevels.ERROR.color}[ERROR]: ${o}${Colors.RESET}`,...t),safe(()=>remote?.log?.("error",o,t));const s=r[0];void 0===s||isNoResponse(s)||forwardErrorToRemote(redactError(s),{source:"Logger.error",message:o})},breadcrumb=(e,r)=>{const o=redactString(e),t=redact(r);breadcrumbs.push({message:o,data:t,timestampUtc:(new Date).toISOString()}),trimBreadcrumbs(),isEnabled()&&isLogLevelAllowed("info")&&console.info(`${Colors.BLUE}[BREADCRUMB]: ${o}${Colors.RESET}`,t??""),safe(()=>remote?.breadcrumb?.(o,t))},recordError=(e,r)=>{const o=redactError(e),t=redact(r);isNoResponse(e)?logInfo(`No response: ${o.message}`):(isEnabled()&&isLogLevelAllowed("error")&&console.error(`${Colors.RED_BOLD}[RECORDED]: ${o.message}${Colors.RESET}`,t??""),forwardErrorToRemote(o,t))},asDict=e=>"object"==typeof e&&null!==e?e:null,traceIdOfTraceparent=e=>headerValue(e,TRACEPARENT_HEADER)?.split("-")[1]??null,headerValue=(e,r)=>{const o=asDict(e);if(!o)return null;const t="function"==typeof o.get?o.get.call(e,r):o[r]??o[r.toLowerCase()];return"string"==typeof t&&""!==t?t:null},requestFailed=(e,r={})=>{const{label:o,expectedStatuses:t=[],...s}=r,n=asDict(e),l=asDict(n?.config),c=asDict(n?.response),i=asDict(c?.data),a="number"==typeof c?.status?c.status:null,d="string"==typeof l?.method?l.method.toUpperCase():null,u="string"==typeof l?.url?l.url.split("?")[0]??null:null,g=o??([d,u].filter(Boolean).join(" ")||"Request");if("CanceledError"===n?.name||"ERR_CANCELED"===n?.code||!0===n?.__CANCEL__)return void logInfo(`${g} canceled`);if("RequestOfflineError"===n?.name)return void logInfo(`${g} not sent (offline)`);if(isNoResponse(e))return void logInfo(`${g} got no response`);if("WorkspaceChangedError"===n?.name||"workspace_changed"===i?.code)return void logInfo(`${g} refused (another workspace)`);if(null!==a&&t.includes(a))return void logInfo(`${g} refused (${a})`);const p="string"==typeof n?.message?n.message:e instanceof Error?e.message:null,f=redactString(null===a?`${g} failed`:`${g} failed (${a})`);isEnabled()&&isLogLevelAllowed(LogLevels.ERROR.level)&&console.error(`${LogLevels.ERROR.color}[ERROR]: ${f}${Colors.RESET}`,redactString(p??"")),safe(()=>remote?.log?.("error",f,[]));const E=redact({source:"Logger.requestFailed",label:g,status:a,method:d,path:u,code:"string"==typeof i?.code?i.code:null,traceId:("string"==typeof i?.traceId?i.traceId:null)??traceIdOfTraceparent(l?.headers),detail:p,...s});forwardErrorToRemote(new Error(f),E)},setUser=(e,r)=>{safe(()=>remote?.setUser?.(e,r))},setAttribute=(e,r)=>{safe(()=>remote?.setAttribute?.(e,r))},trackScreen=(e,r)=>{e!==currentScreen&&(currentScreen=e,screenHistory.push(e),screenHistory.length>loggerOptions.screenHistoryLimit&&(screenHistory=screenHistory.slice(screenHistory.length-loggerOptions.screenHistoryLimit)),breadcrumb(`Screen: ${e}`,r))},getCurrentScreen=()=>currentScreen,getScreenHistory=()=>[...screenHistory],getBreadcrumbs=()=>[...breadcrumbs];export const Logger={debug:logDebug,info:logInfo,warn:logWarning,error:logError,breadcrumb:breadcrumb,recordError:recordError,requestFailed:requestFailed,setUser:setUser,setAttribute:setAttribute,trackScreen:trackScreen,getCurrentScreen:getCurrentScreen,getScreenHistory:getScreenHistory,getBreadcrumbs:getBreadcrumbs};
@@ -1,16 +1,16 @@
1
1
  import type { AxiosInstance } from "axios";
2
- export declare const CLIENT_BUILD_HEADER = "X-Client-Build";
3
- export declare const APP_BUILD_HEADER = "X-App-Build";
4
- export declare const CLIENT_KIND_HEADER = "X-Client-Kind";
5
- export declare const ACCOUNT_ID_HEADER = "X-Account-Id";
2
+ export declare const CLIENT_BUILD_HEADER = "Client-Build";
3
+ export declare const APP_BUILD_HEADER = "App-Build";
4
+ export declare const CLIENT_KIND_HEADER = "Client-Kind";
5
+ export declare const ACCOUNT_ID_HEADER = "Account-Id";
6
6
  /** The server picks session rules and the minimum version per kind; the names match its enum. */
7
7
  export type ClientKind = "Browser" | "MobileApp";
8
8
  export declare const CLIENT_KIND: ClientKind;
9
9
  /** `<appVersion>+<commit>`, `<appVersion>` when no commit was stamped, `null` before init. */
10
10
  export declare const getClientBuild: () => string | null;
11
11
  /**
12
- * Stamps X-Client-Kind, X-Client-Build and X-App-Build on every request.
13
- * X-App-Build is the whole build number the server compares with its minimum;
12
+ * Stamps Client-Kind, Client-Build and App-Build on every request.
13
+ * App-Build is the whole build number the server compares with its minimum;
14
14
  * it is left off when the build is unknown, because the server never refuses a
15
15
  * request without it and a guessed number could strand a current build. A value the app
16
16
  * already set (a default header, or a per-request one) wins, so an app that
@@ -29,7 +29,7 @@ export interface AccountStampedConfig {
29
29
  _accountId?: string | null;
30
30
  }
31
31
  /**
32
- * Stamps X-Account-Id once, on the first send, and records it on the config. A request must
32
+ * Stamps Account-Id once, on the first send, and records it on the config. A request must
33
33
  * never run in a workspace other than the one it was made in, so every resend (the retry
34
34
  * policy, a 401 replay, a refresh replay) keeps the first stamp even after the user switched.
35
35
  * A header the caller set itself (an outbox item naming its own workspace) wins over the provider.
@@ -5,7 +5,7 @@ import type { AxiosInstance } from "axios";
5
5
  * errors included; cross-origin it is readable only when the API lists it in
6
6
  * `Access-Control-Expose-Headers`.
7
7
  */
8
- export declare const MIN_APP_VERSION_HEADER = "X-Min-App-Version";
8
+ export declare const MIN_APP_VERSION_HEADER = "Min-App-Version";
9
9
  export type MinAppVersionListener = (minAppVersion: number) => void;
10
10
  /** The floor the API last named, or `null` before any response carried one. */
11
11
  export declare const getMinAppVersion: () => number | null;
@@ -17,8 +17,7 @@ export declare const getMinAppVersion: () => number | null;
17
17
  */
18
18
  export declare const addMinAppVersionListener: (listener: MinAppVersionListener) => (() => void);
19
19
  /**
20
- * Reads the floor off every response the client receives, a rejected one too:
21
- * a 426 Upgrade Required is exactly the case the floor exists for.
20
+ * Reads the floor off every response the client receives, a rejected one too.
22
21
  */
23
22
  export declare const readMinAppVersion: (client: AxiosInstance) => void;
24
23
  //# sourceMappingURL=minAppVersion.d.ts.map
@@ -1,17 +1,20 @@
1
1
  import type { AxiosInstance } from "axios";
2
+ export declare const TRACEPARENT_HEADER = "traceparent";
2
3
  /**
3
- * A fresh v4 uuid. `crypto.randomUUID` exists only in a secure context (HTTPS or localhost) and
4
- * not at all on Hermes, so the id falls back to `getRandomValues`, then to `Math.random`. A
5
- * correlation id only has to be unique enough to find one request in the logs; it is never a secret.
4
+ * A fresh W3C traceparent, version 00, sampled: the header value and its 32-hex trace id. The ids
5
+ * only have to be unique enough to find one request in the logs; they are never secrets.
6
6
  */
7
- export declare const newCorrelationId: () => string;
7
+ export declare const newTraceparent: () => {
8
+ header: string;
9
+ traceId: string;
10
+ };
8
11
  /**
9
- * Applies the configured timeout and the correlation id per request, read on every send so a
12
+ * Applies the configured timeout and the traceparent per request, read on every send so a
10
13
  * value set after import still applies (the same reason `applyConfiguredBaseUrl` exists).
11
14
  * - `timeoutMs`: used when the request carries no timeout of its own; a request's own axios
12
15
  * `timeout` wins. 0, either way, means no timeout (axios's own meaning).
13
- * - `correlationIdHeader`: a fresh uuid unless the request already carries one. A retry
14
- * resends the same config, so it keeps the id the first attempt went out with.
16
+ * - `traceparent`: a fresh one unless the request already carries one. A retry
17
+ * resends the same config, so it keeps the value the first attempt went out with.
15
18
  *
16
19
  * axios fills a missing `timeout` with its own default of 0, which would make "this request
17
20
  * set none" and "this request asked for none" look alike. The client's default is therefore
@@ -20,9 +20,9 @@ export declare const IDEMPOTENCY_KEY_HEADER = "Idempotency-Key";
20
20
  export declare const isRetryableStatus: (status: number | undefined) => boolean;
21
21
  export declare const isNeverSentError: (error: AxiosError) => boolean;
22
22
  /**
23
- * The wait a refusal named, in milliseconds: the `Retry-After` header (seconds)
24
- * or a `retryAfterSeconds` body field. `null` when it named none. Cross-origin,
25
- * the header is readable only when the API lists it in `Access-Control-Expose-Headers`.
23
+ * The wait a refusal named, in milliseconds: the `Retry-After` header (seconds).
24
+ * `null` when it named none. Cross-origin, the header is readable only when the API
25
+ * lists it in `Access-Control-Expose-Headers`.
26
26
  */
27
27
  export declare const retryAfterMs: (error: AxiosError) => number | null;
28
28
  /**
@@ -1,5 +1,9 @@
1
1
  import { type SessionEndReason } from "../auth/authStore";
2
2
  import type { UserAuthOptions } from "../initUserAuth";
3
+ /** The 401 `code` the server sends when it revoked the session (a revoked token or a rejected cookie stamp). */
4
+ export declare const SESSION_REVOKED_CODE = "session_revoked";
5
+ /** The 401 `code` the server sends when the refresh token has expired. */
6
+ export declare const SESSION_EXPIRED_CODE = "session_expired";
3
7
  /**
4
8
  * The one token-refresh flow in the library, run by userClient's interceptors.
5
9
  * The library calls the refresh endpoint itself, so it can tell a rejected
@@ -33,14 +37,13 @@ export declare const getAccountIdProvider: () => UserAuthOptions["accountId"];
33
37
  /** The refresh endpoint's path, once initUserAuth has run. */
34
38
  export declare const getRefreshPath: () => string | undefined;
35
39
  export declare const dispatchLogout: () => Promise<void>;
36
- export declare const SIGN_OUT_REASON_HEADER = "X-Sign-Out-Reason";
37
- /** The server's sign-out reason from response headers (AxiosHeaders or a plain object), or null. */
38
- export declare const readSignOutReason: (headers: unknown) => string | null;
39
40
  /**
40
41
  * The session is over: clear it (tokens and session user removed, listeners told why, with
41
- * the server's reason), then dispatch the app's logout.
42
+ * the server's session code), then dispatch the app's logout.
42
43
  */
43
- export declare const endSessionAndLogout: (reason: SessionEndReason, signOutReason: string | null) => Promise<void>;
44
+ export declare const endSessionAndLogout: (reason: SessionEndReason, code: string | null) => Promise<void>;
45
+ /** The server's session code in a 401 body (`session_revoked`, `session_expired`), or null. */
46
+ export declare const sessionCodeOf: (data: unknown) => string | null;
44
47
  export declare const isRefreshInFlight: () => boolean;
45
48
  /** Opens the replacement window for one flagged request; call the returned function once it settles. */
46
49
  export declare const beginSessionReplacement: () => (() => void);
@@ -1,7 +1,7 @@
1
1
  import { type AxiosInstance } from "axios";
2
2
  import "../types/axios";
3
3
  export type { RefreshableStore } from "./tokenRefresh";
4
- export { injectStore, injectUserAuth, resetRefreshState, SIGN_OUT_REASON_HEADER, } from "./tokenRefresh";
4
+ export { injectStore, injectUserAuth, resetRefreshState, SESSION_EXPIRED_CODE, SESSION_REVOKED_CODE, } from "./tokenRefresh";
5
5
  /**
6
6
  * Thrown by the request interceptor when the device is offline, before the
7
7
  * request ever reaches the adapter (and therefore the network). Distinct from
@@ -11,28 +11,6 @@ export { injectStore, injectUserAuth, resetRefreshState, SIGN_OUT_REASON_HEADER,
11
11
  export declare class RequestOfflineError extends Error {
12
12
  constructor(message?: string);
13
13
  }
14
- /**
15
- * Sub-codes a 401 response body carries when the session itself is dead
16
- * (terminated by an admin, or expired server-side) rather than merely
17
- * out-of-date. These never warrant a refresh attempt — only logout.
18
- */
19
- export declare const SESSION_TERMINATION_CODES: {
20
- readonly TERMINATED: "SESSION_TERMINATED";
21
- readonly EXPIRED: "SESSION_EXPIRED";
22
- };
23
- export type SessionTerminationCode = (typeof SESSION_TERMINATION_CODES)[keyof typeof SESSION_TERMINATION_CODES];
24
- /**
25
- * The header is the AUTHORITATIVE signal, verified against the backend:
26
- * `WeborityJwtMiddleware.ReturnUnauthorized` answers an invalidated session with
27
- * `401` + `X-Security-Stamp-Invalid: true` and a body of
28
- * `{ error: 'Unauthorized', message: '...' }` — no code field at all, and
29
- * `error` is a string rather than an object. An earlier version of this checked
30
- * only body fields and would therefore never have fired against a real server.
31
- *
32
- * The body codes below are kept as a secondary path for any head that does send
33
- * an explicit sub-code; they match on exact strings, so looking is free.
34
- */
35
- export declare const SESSION_INVALID_HEADER = "x-security-stamp-invalid";
36
14
  declare const userClient: AxiosInstance;
37
15
  export default userClient;
38
16
  //# sourceMappingURL=userClient.d.ts.map
@@ -33,12 +33,9 @@ export type SessionEndReason = "signedOut" | "rejected" | "terminated" | "corrup
33
33
  /** What else is known about a session end, beside its reason. */
34
34
  export interface SessionEndDetail {
35
35
  /**
36
- * The server's own name for why it ended the session, from the sign-out-reason response
37
- * header (`X-Sign-Out-Reason` by default, `initUserAuth({ signOutReasonHeader })`), on a
38
- * terminated session or a refused refresh. `null` when the server named none, and always
39
- * `null` for `signedOut` and `corrupt` unless the app passes one.
36
+ * The server's session code (`session_revoked`, `session_expired`) when the server ended the session; null when the app did.
40
37
  */
41
- signOutReason: string | null;
38
+ code: string | null;
42
39
  }
43
40
  export type SessionEndedListener = (reason: SessionEndReason, detail: SessionEndDetail) => void;
44
41
  /**
@@ -148,7 +145,7 @@ export declare const addSessionEndedListener: (listener: SessionEndedListener) =
148
145
  * flow and the app's own sign-out can both call it without a double event.
149
146
  * The library calls it itself with `rejected` when the refresh endpoint refuses
150
147
  * the refresh token and `terminated` when the API reports the session dead,
151
- * with the server's sign-out reason in `detail`.
148
+ * with the server's session code in `detail`.
152
149
  */
153
150
  export declare const clearSession: (reason?: SessionEndReason, detail?: Partial<SessionEndDetail>) => Promise<void>;
154
151
  export type { KeychainLike, SecureCredentials };
@@ -27,12 +27,12 @@ export interface Config {
27
27
  appId: string | null;
28
28
  /** The app's user-visible version string, e.g. `'1.4.2'`. Same rationale as `appId`. */
29
29
  appVersion: string | null;
30
- /** The short git sha stamped into the build; with `appVersion` it makes the X-Client-Build header. */
30
+ /** The short git sha stamped into the build; with `appVersion` it makes the Client-Build header. */
31
31
  commit: string | null;
32
32
  /**
33
33
  * The app's internal build number (`VERSION_INTERNAL`: Android versionCode,
34
34
  * iOS CFBundleVersion). The version check compares it with the API's
35
- * `X-Min-App-Version`. Falls back to expo-application when unset.
35
+ * `Min-App-Version`. Falls back to expo-application when unset.
36
36
  */
37
37
  appBuild: number | null;
38
38
  /**
@@ -53,12 +53,6 @@ export interface Config {
53
53
  timeoutMs: number;
54
54
  /** How many times a failed request is resent under the retry rule. 0 turns retrying off. Default 3. */
55
55
  retries: number;
56
- /**
57
- * Header that carries a fresh id (a uuid) on every request, for tracing one request across
58
- * the app, the API and its logs. A retry keeps the id it first went out with. `null`
59
- * sends none. Default `'X-Correlation-Id'`.
60
- */
61
- correlationIdHeader: string | null;
62
56
  }
63
57
  /**
64
58
  * Info lines (each token refresh, each unauthorised URL) reach the device log
@@ -68,7 +62,6 @@ export interface Config {
68
62
  export declare const DEFAULT_LOG_LEVEL: LogLevel;
69
63
  export declare const DEFAULT_TIMEOUT_MS = 30000;
70
64
  export declare const DEFAULT_RETRIES = 3;
71
- export declare const DEFAULT_CORRELATION_ID_HEADER = "X-Correlation-Id";
72
65
  /**
73
66
  * Set global configuration for all Webority packages
74
67
  */
@@ -2,19 +2,13 @@
2
2
  * Normalizes any failure a thunk, a service or the RTK Query base query can see into one
3
3
  * `ApiError`. Identical source in @webority/web-core and @webority/mobile-core.
4
4
  *
5
- * Bodies read, newest first: the standard body `{ code, message, traceId, errors }`,
6
- * where `errors` is a ModelState dictionary (`{ Field: ["msg"] }`) or a list of
7
- * `{ field, message, reference }` (a refusal that names its fields),
8
- * ProblemDetails `{ title, detail, errors }` from APIs not yet moved, legacy `{ error }` and
9
- * `{ message }`, and a plain-text body.
5
+ * The body read is the RFC 9457 problem `{ type, title, status, detail, code, traceId, errors }`,
6
+ * where `errors` is a ModelState dictionary (`{ Field: ["msg"] }`) or a list of `{ field, message }`.
10
7
  *
11
- * Message precedence is fixed (react.md): first field error, then `message`, `detail`, a
12
- * legacy `error`, `title`, then `Request failed (<status>)`. `title` is last because it is
13
- * the ProblemDetails category ("Bad Request"), not the curated sentence.
14
- *
15
- * Never a `message`: anything that reads like an exception dump, and a 5xx body unless it is
16
- * coded (not `internal_error`) and its `message` is user-safe. The server's text goes on
17
- * `detail` for the logger either way.
8
+ * Message precedence (react.md): first field error, form error, `detail`, `title`, a plain-text
9
+ * body, then `Request failed (<status>)`. A 5xx shows `detail` only when it carries a code other
10
+ * than `internal_error`. The server's text goes on `diagnostic` for the logger, never the screen.
11
+ * The trace id falls back to the request's own `traceparent`, so a lost request keeps a reference.
18
12
  */
19
13
  export interface ApiError {
20
14
  /** Stable snake_case branch key from the server (`not_found`, `validation_failed`). Branch on it, never render it. */
@@ -30,7 +24,7 @@ export interface ApiError {
30
24
  /** The server's trace id, for a support reference. */
31
25
  traceId: string | null;
32
26
  /** What the server or runtime actually said. For the logger, never for the screen. */
33
- detail: string | null;
27
+ diagnostic: string | null;
34
28
  }
35
29
  export declare const SERVER_FAILURE_MESSAGE = "Something went wrong on our side. Please try again in a moment.";
36
30
  export declare const OFFLINE_MESSAGE = "You appear to be offline. Check your connection and try again.";
@@ -36,12 +36,12 @@ export { buildCurl, logCurl } from "./api/curl";
36
36
  export type { MinAppVersionListener } from "./api/minAppVersion";
37
37
  export { addMinAppVersionListener, getMinAppVersion, MIN_APP_VERSION_HEADER, } from "./api/minAppVersion";
38
38
  export { default as publicClient } from "./api/publicClient";
39
- export { applyRequestDefaults, newCorrelationId } from "./api/requestDefaults";
39
+ export { applyRequestDefaults, newTraceparent, TRACEPARENT_HEADER } from "./api/requestDefaults";
40
40
  export type { RetryPolicy } from "./api/retry";
41
41
  export { attachRetry, IDEMPOTENCY_KEY_HEADER, isNeverSentError, isRetryableFailure, isRetryableStatus, retryAfterMs, } from "./api/retry";
42
42
  export { refreshAccessToken } from "./api/tokenRefresh";
43
- export type { RefreshableStore, SessionTerminationCode } from "./api/userClient";
44
- export { default as userClient, injectStore, injectUserAuth, RequestOfflineError, resetRefreshState, SESSION_TERMINATION_CODES, SIGN_OUT_REASON_HEADER, } from "./api/userClient";
43
+ export type { RefreshableStore } from "./api/userClient";
44
+ export { default as userClient, injectStore, injectUserAuth, RequestOfflineError, resetRefreshState, SESSION_EXPIRED_CODE, SESSION_REVOKED_CODE, } from "./api/userClient";
45
45
  export { isWorkspaceChangedError, WORKSPACE_CHANGED_CODE, WorkspaceChangedError, } from "./api/workspace";
46
46
  export type { KeychainLike, LegacyTokenKeys, SecureCredentials, SessionEndDetail, SessionEndedListener, SessionEndReason, StoredToken, } from "./auth/authStore";
47
47
  export { ACCESS_TOKEN_KEY, addSessionEndedListener, clearSession, getSessionUser, getToken, LEGACY_REFRESH_TOKEN_LIFETIME_MS, REFRESH_TOKEN_KEY, removeSessionUser, removeToken, SESSION_USER_KEY, setKeychainImplementation, setLegacyTokenKeys, storeSessionUser, storeToken, } from "./auth/authStore";
@@ -31,14 +31,14 @@ export interface InitConfig {
31
31
  * user-visible version and its internal build number (`VERSION_INTERNAL`).
32
32
  * Every Webority app already has them in `appsettings.Compiled.json`, which
33
33
  * is why they come from config rather than across the native bridge. The
34
- * version check compares `appBuild` with the API's `X-Min-App-Version`.
34
+ * version check compares `appBuild` with the API's `Min-App-Version`.
35
35
  */
36
36
  appId?: string;
37
37
  appVersion?: string;
38
38
  appBuild?: number;
39
39
  /** The numeric Apple App Store id; the iOS update button needs it. */
40
40
  appStoreId?: string;
41
- /** The build's short git sha (`COMMIT` in appsettings); sent as `X-Client-Build: <appVersion>+<commit>`. */
41
+ /** The build's short git sha (`COMMIT` in appsettings); sent as `Client-Build: <appVersion>+<commit>`. */
42
42
  commit?: string;
43
43
  /**
44
44
  * Log a redacted curl line per request. Off by default; it is a debugging
@@ -49,8 +49,6 @@ export interface InitConfig {
49
49
  timeoutMs?: number;
50
50
  /** Retries under the retry rule. Defaults to 3; 0 turns retrying off. */
51
51
  retries?: number;
52
- /** Header for the per-request correlation id. Defaults to `'X-Correlation-Id'`; `null` sends none. */
53
- correlationIdHeader?: string | null;
54
52
  /**
55
53
  * The native modules that fill the seams the library does not import.
56
54
  *
@@ -36,20 +36,13 @@ export interface UserAuthOptions {
36
36
  logout: () => unknown;
37
37
  refresh: TokenRefreshConfig;
38
38
  /**
39
- * The account the signed-in user is working in, sent as `X-Account-Id` on
39
+ * The account the signed-in user is working in, sent as `Account-Id` on
40
40
  * every userClient request. Read when a request is first sent and kept for its
41
41
  * resends, so a request never runs in a workspace the user switched to after
42
42
  * making it; a request that sets the header itself keeps its own value.
43
43
  * Omit it in a product whose API takes the account from the token alone.
44
44
  */
45
45
  accountId?: AccountIdProvider;
46
- /**
47
- * The response header in which the API names why it ended a session. A 401 carrying it is a
48
- * revoked session: no refresh is tried, the session is cleared as `terminated`, and the
49
- * value reaches every `addSessionEndedListener` listener as `detail.signOutReason`. It is
50
- * read from a refused refresh too. Default `'X-Sign-Out-Reason'`; `null` turns it off.
51
- */
52
- signOutReasonHeader?: string | null;
53
46
  /**
54
47
  * The secure-store keys the app kept its session under before this library. The first token
55
48
  * read that finds the library's keys empty moves a session found there and deletes the old
@@ -2,7 +2,7 @@
2
2
  * Build-number arithmetic for the server-driven update check, shared word for
3
3
  * word by web-core and mobile-core.
4
4
  *
5
- * The API's `X-Min-App-Version` is the lowest internal build number it still
5
+ * The API's `Min-App-Version` is the lowest internal build number it still
6
6
  * supports for the calling client kind, and the app's own build number is an
7
7
  * integer too (`VERSION_INTERNAL` on mobile, `appBuild` on web). The comparison
8
8
  * is integer against integer, never semver against semver.
@@ -20,7 +20,7 @@ export interface ParsedVersion {
20
20
  patch: number;
21
21
  prerelease: string;
22
22
  }
23
- /** @deprecated The store is no longer read; the minimum comes from `X-Min-App-Version`. */
23
+ /** @deprecated The store is no longer read; the minimum comes from `Min-App-Version`. */
24
24
  export interface VersionData {
25
25
  version: string | null;
26
26
  released?: string | null;
@@ -30,7 +30,7 @@ export interface VersionData {
30
30
  country?: string;
31
31
  lastChecked: string;
32
32
  }
33
- /** @deprecated The store is no longer read; the minimum comes from `X-Min-App-Version`. */
33
+ /** @deprecated The store is no longer read; the minimum comes from `Min-App-Version`. */
34
34
  export interface VersionComparison {
35
35
  needsUpdate: boolean;
36
36
  updateType: UpdateType;
@@ -48,7 +48,7 @@ export interface UpdateInfo {
48
48
  export interface VersionCheckType {
49
49
  /**
50
50
  * Whether this build is below the minimum the API last sent in
51
- * `X-Min-App-Version`. Resolves "no update" until a reply carried one, and
51
+ * `Min-App-Version`. Resolves "no update" until a reply carried one, and
52
52
  * rejects only when the app's build number is unknown.
53
53
  */
54
54
  isNewVersionAvailable: () => Promise<VersionCheckResult>;
@@ -63,7 +63,7 @@ export interface VersionCheckType {
63
63
  export declare const VersionCheck: VersionCheckType;
64
64
  /**
65
65
  * Whether this build must update, from the minimum the API sends in
66
- * `X-Min-App-Version`. Re-renders the moment a reply raises the minimum, so a
66
+ * `Min-App-Version`. Re-renders the moment a reply raises the minimum, so a
67
67
  * minimum raised mid-session opens the ForceUpdateDialog without a restart.
68
68
  *
69
69
  * @param isAppReady - Whether the app is ready to show the prompt
@@ -1,16 +1,16 @@
1
1
  import type { AxiosInstance } from "axios";
2
- export declare const CLIENT_BUILD_HEADER = "X-Client-Build";
3
- export declare const APP_BUILD_HEADER = "X-App-Build";
4
- export declare const CLIENT_KIND_HEADER = "X-Client-Kind";
5
- export declare const ACCOUNT_ID_HEADER = "X-Account-Id";
2
+ export declare const CLIENT_BUILD_HEADER = "Client-Build";
3
+ export declare const APP_BUILD_HEADER = "App-Build";
4
+ export declare const CLIENT_KIND_HEADER = "Client-Kind";
5
+ export declare const ACCOUNT_ID_HEADER = "Account-Id";
6
6
  /** The server picks session rules and the minimum version per kind; the names match its enum. */
7
7
  export type ClientKind = "Browser" | "MobileApp";
8
8
  export declare const CLIENT_KIND: ClientKind;
9
9
  /** `<appVersion>+<commit>`, `<appVersion>` when no commit was stamped, `null` before init. */
10
10
  export declare const getClientBuild: () => string | null;
11
11
  /**
12
- * Stamps X-Client-Kind, X-Client-Build and X-App-Build on every request.
13
- * X-App-Build is the whole build number the server compares with its minimum;
12
+ * Stamps Client-Kind, Client-Build and App-Build on every request.
13
+ * App-Build is the whole build number the server compares with its minimum;
14
14
  * it is left off when the build is unknown, because the server never refuses a
15
15
  * request without it and a guessed number could strand a current build. A value the app
16
16
  * already set (a default header, or a per-request one) wins, so an app that
@@ -29,7 +29,7 @@ export interface AccountStampedConfig {
29
29
  _accountId?: string | null;
30
30
  }
31
31
  /**
32
- * Stamps X-Account-Id once, on the first send, and records it on the config. A request must
32
+ * Stamps Account-Id once, on the first send, and records it on the config. A request must
33
33
  * never run in a workspace other than the one it was made in, so every resend (the retry
34
34
  * policy, a 401 replay, a refresh replay) keeps the first stamp even after the user switched.
35
35
  * A header the caller set itself (an outbox item naming its own workspace) wins over the provider.
@@ -5,7 +5,7 @@ import type { AxiosInstance } from "axios";
5
5
  * errors included; cross-origin it is readable only when the API lists it in
6
6
  * `Access-Control-Expose-Headers`.
7
7
  */
8
- export declare const MIN_APP_VERSION_HEADER = "X-Min-App-Version";
8
+ export declare const MIN_APP_VERSION_HEADER = "Min-App-Version";
9
9
  export type MinAppVersionListener = (minAppVersion: number) => void;
10
10
  /** The floor the API last named, or `null` before any response carried one. */
11
11
  export declare const getMinAppVersion: () => number | null;
@@ -17,8 +17,7 @@ export declare const getMinAppVersion: () => number | null;
17
17
  */
18
18
  export declare const addMinAppVersionListener: (listener: MinAppVersionListener) => (() => void);
19
19
  /**
20
- * Reads the floor off every response the client receives, a rejected one too:
21
- * a 426 Upgrade Required is exactly the case the floor exists for.
20
+ * Reads the floor off every response the client receives, a rejected one too.
22
21
  */
23
22
  export declare const readMinAppVersion: (client: AxiosInstance) => void;
24
23
  //# sourceMappingURL=minAppVersion.d.ts.map
@@ -1,17 +1,20 @@
1
1
  import type { AxiosInstance } from "axios";
2
+ export declare const TRACEPARENT_HEADER = "traceparent";
2
3
  /**
3
- * A fresh v4 uuid. `crypto.randomUUID` exists only in a secure context (HTTPS or localhost) and
4
- * not at all on Hermes, so the id falls back to `getRandomValues`, then to `Math.random`. A
5
- * correlation id only has to be unique enough to find one request in the logs; it is never a secret.
4
+ * A fresh W3C traceparent, version 00, sampled: the header value and its 32-hex trace id. The ids
5
+ * only have to be unique enough to find one request in the logs; they are never secrets.
6
6
  */
7
- export declare const newCorrelationId: () => string;
7
+ export declare const newTraceparent: () => {
8
+ header: string;
9
+ traceId: string;
10
+ };
8
11
  /**
9
- * Applies the configured timeout and the correlation id per request, read on every send so a
12
+ * Applies the configured timeout and the traceparent per request, read on every send so a
10
13
  * value set after import still applies (the same reason `applyConfiguredBaseUrl` exists).
11
14
  * - `timeoutMs`: used when the request carries no timeout of its own; a request's own axios
12
15
  * `timeout` wins. 0, either way, means no timeout (axios's own meaning).
13
- * - `correlationIdHeader`: a fresh uuid unless the request already carries one. A retry
14
- * resends the same config, so it keeps the id the first attempt went out with.
16
+ * - `traceparent`: a fresh one unless the request already carries one. A retry
17
+ * resends the same config, so it keeps the value the first attempt went out with.
15
18
  *
16
19
  * axios fills a missing `timeout` with its own default of 0, which would make "this request
17
20
  * set none" and "this request asked for none" look alike. The client's default is therefore
@@ -20,9 +20,9 @@ export declare const IDEMPOTENCY_KEY_HEADER = "Idempotency-Key";
20
20
  export declare const isRetryableStatus: (status: number | undefined) => boolean;
21
21
  export declare const isNeverSentError: (error: AxiosError) => boolean;
22
22
  /**
23
- * The wait a refusal named, in milliseconds: the `Retry-After` header (seconds)
24
- * or a `retryAfterSeconds` body field. `null` when it named none. Cross-origin,
25
- * the header is readable only when the API lists it in `Access-Control-Expose-Headers`.
23
+ * The wait a refusal named, in milliseconds: the `Retry-After` header (seconds).
24
+ * `null` when it named none. Cross-origin, the header is readable only when the API
25
+ * lists it in `Access-Control-Expose-Headers`.
26
26
  */
27
27
  export declare const retryAfterMs: (error: AxiosError) => number | null;
28
28
  /**
@@ -1,5 +1,9 @@
1
1
  import { type SessionEndReason } from "../auth/authStore.js";
2
2
  import type { UserAuthOptions } from "../initUserAuth.js";
3
+ /** The 401 `code` the server sends when it revoked the session (a revoked token or a rejected cookie stamp). */
4
+ export declare const SESSION_REVOKED_CODE = "session_revoked";
5
+ /** The 401 `code` the server sends when the refresh token has expired. */
6
+ export declare const SESSION_EXPIRED_CODE = "session_expired";
3
7
  /**
4
8
  * The one token-refresh flow in the library, run by userClient's interceptors.
5
9
  * The library calls the refresh endpoint itself, so it can tell a rejected
@@ -33,14 +37,13 @@ export declare const getAccountIdProvider: () => UserAuthOptions["accountId"];
33
37
  /** The refresh endpoint's path, once initUserAuth has run. */
34
38
  export declare const getRefreshPath: () => string | undefined;
35
39
  export declare const dispatchLogout: () => Promise<void>;
36
- export declare const SIGN_OUT_REASON_HEADER = "X-Sign-Out-Reason";
37
- /** The server's sign-out reason from response headers (AxiosHeaders or a plain object), or null. */
38
- export declare const readSignOutReason: (headers: unknown) => string | null;
39
40
  /**
40
41
  * The session is over: clear it (tokens and session user removed, listeners told why, with
41
- * the server's reason), then dispatch the app's logout.
42
+ * the server's session code), then dispatch the app's logout.
42
43
  */
43
- export declare const endSessionAndLogout: (reason: SessionEndReason, signOutReason: string | null) => Promise<void>;
44
+ export declare const endSessionAndLogout: (reason: SessionEndReason, code: string | null) => Promise<void>;
45
+ /** The server's session code in a 401 body (`session_revoked`, `session_expired`), or null. */
46
+ export declare const sessionCodeOf: (data: unknown) => string | null;
44
47
  export declare const isRefreshInFlight: () => boolean;
45
48
  /** Opens the replacement window for one flagged request; call the returned function once it settles. */
46
49
  export declare const beginSessionReplacement: () => (() => void);