@webority/mobile-core 0.91.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,7 +1,7 @@
1
1
  import { type AxiosInstance } from "axios";
2
2
  import "../types/axios.js";
3
3
  export type { RefreshableStore } from "./tokenRefresh.js";
4
- export { injectStore, injectUserAuth, resetRefreshState, SIGN_OUT_REASON_HEADER, } from "./tokenRefresh.js";
4
+ export { injectStore, injectUserAuth, resetRefreshState, SESSION_EXPIRED_CODE, SESSION_REVOKED_CODE, } from "./tokenRefresh.js";
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.js";
36
36
  export type { MinAppVersionListener } from "./api/minAppVersion.js";
37
37
  export { addMinAppVersionListener, getMinAppVersion, MIN_APP_VERSION_HEADER, } from "./api/minAppVersion.js";
38
38
  export { default as publicClient } from "./api/publicClient.js";
39
- export { applyRequestDefaults, newCorrelationId } from "./api/requestDefaults.js";
39
+ export { applyRequestDefaults, newTraceparent, TRACEPARENT_HEADER } from "./api/requestDefaults.js";
40
40
  export type { RetryPolicy } from "./api/retry.js";
41
41
  export { attachRetry, IDEMPOTENCY_KEY_HEADER, isNeverSentError, isRetryableFailure, isRetryableStatus, retryAfterMs, } from "./api/retry.js";
42
42
  export { refreshAccessToken } from "./api/tokenRefresh.js";
43
- export type { RefreshableStore, SessionTerminationCode } from "./api/userClient.js";
44
- export { default as userClient, injectStore, injectUserAuth, RequestOfflineError, resetRefreshState, SESSION_TERMINATION_CODES, SIGN_OUT_REASON_HEADER, } from "./api/userClient.js";
43
+ export type { RefreshableStore } from "./api/userClient.js";
44
+ export { default as userClient, injectStore, injectUserAuth, RequestOfflineError, resetRefreshState, SESSION_EXPIRED_CODE, SESSION_REVOKED_CODE, } from "./api/userClient.js";
45
45
  export { isWorkspaceChangedError, WORKSPACE_CHANGED_CODE, WorkspaceChangedError, } from "./api/workspace.js";
46
46
  export type { KeychainLike, LegacyTokenKeys, SecureCredentials, SessionEndDetail, SessionEndedListener, SessionEndReason, StoredToken, } from "./auth/authStore.js";
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.js";
@@ -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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webority/mobile-core",
3
- "version": "0.91.0",
3
+ "version": "0.93.0",
4
4
  "description": "Platform layer for Webority React Native apps: HTTP clients, auth/token storage, config, logging, formatters, validators, network status, permissions, storage, version checks and over-the-air updates. No UI.",
5
5
  "keywords": [
6
6
  "react-native",