@webority/mobile-core 0.1.0 → 0.2.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 (185) hide show
  1. package/README.md +32 -0
  2. package/lib/commonjs/api/clientHeaders.js +1 -0
  3. package/lib/commonjs/api/minAppVersion.js +1 -0
  4. package/lib/commonjs/api/publicClient.js +1 -1
  5. package/lib/commonjs/api/requestDefaults.js +1 -0
  6. package/lib/commonjs/api/retry.js +1 -1
  7. package/lib/commonjs/api/tokenRefresh.js +1 -1
  8. package/lib/commonjs/api/userClient.js +1 -1
  9. package/lib/commonjs/auth/authStore.js +1 -1
  10. package/lib/commonjs/auth/index.js +1 -1
  11. package/lib/commonjs/config/index.js +1 -1
  12. package/lib/commonjs/errors/extractApiError.js +1 -0
  13. package/lib/commonjs/errors/index.js +1 -0
  14. package/lib/commonjs/formatters/currency.js +1 -1
  15. package/lib/commonjs/formatters/date.js +1 -1
  16. package/lib/commonjs/formatters/dateMath.js +1 -1
  17. package/lib/commonjs/formatters/formatConfig.js +1 -0
  18. package/lib/commonjs/formatters/house.js +1 -0
  19. package/lib/commonjs/formatters/index.js +1 -1
  20. package/lib/commonjs/formatters/number.js +1 -1
  21. package/lib/commonjs/index.js +1 -1
  22. package/lib/commonjs/initSDK.js +1 -1
  23. package/lib/commonjs/initUserAuth.js +1 -1
  24. package/lib/commonjs/logger/index.js +1 -1
  25. package/lib/commonjs/query/apiBaseQuery.js +1 -0
  26. package/lib/commonjs/query/createAppApi.js +1 -0
  27. package/lib/commonjs/query/index.js +1 -0
  28. package/lib/commonjs/query/listeners.js +1 -0
  29. package/lib/commonjs/query/paging.js +1 -0
  30. package/lib/commonjs/query/tags.js +1 -0
  31. package/lib/commonjs/redux/errorToastMiddleware.js +1 -0
  32. package/lib/commonjs/redux/index.js +1 -0
  33. package/lib/commonjs/redux/rootReducer.js +1 -0
  34. package/lib/commonjs/redux/serializableCheck.js +1 -0
  35. package/lib/commonjs/versionCheck/buildNumber.js +1 -0
  36. package/lib/commonjs/versionCheck/index.js +1 -1
  37. package/lib/module/api/baseUrl.js +1 -1
  38. package/lib/module/api/clientHeaders.js +1 -0
  39. package/lib/module/api/curl.js +1 -1
  40. package/lib/module/api/minAppVersion.js +1 -0
  41. package/lib/module/api/multipart.js +1 -1
  42. package/lib/module/api/publicClient.js +1 -1
  43. package/lib/module/api/requestDefaults.js +1 -0
  44. package/lib/module/api/responseBodyText.js +1 -1
  45. package/lib/module/api/retry.js +1 -1
  46. package/lib/module/api/tokenRefresh.js +1 -1
  47. package/lib/module/api/userClient.js +1 -1
  48. package/lib/module/auth/authStore.js +1 -1
  49. package/lib/module/auth/index.js +1 -1
  50. package/lib/module/auth/jwt.js +1 -1
  51. package/lib/module/config/index.js +1 -1
  52. package/lib/module/deepLink/index.js +1 -1
  53. package/lib/module/download/adapters/expoFs.js +1 -1
  54. package/lib/module/download/adapters/shared.js +1 -1
  55. package/lib/module/download/index.js +1 -1
  56. package/lib/module/errors/extractApiError.js +1 -0
  57. package/lib/module/errors/index.js +1 -0
  58. package/lib/module/formatters/currency.js +1 -1
  59. package/lib/module/formatters/date.js +1 -1
  60. package/lib/module/formatters/dateMath.js +1 -1
  61. package/lib/module/formatters/formatConfig.js +1 -0
  62. package/lib/module/formatters/house.js +1 -0
  63. package/lib/module/formatters/index.js +1 -1
  64. package/lib/module/formatters/initials.js +1 -1
  65. package/lib/module/formatters/intlCache.js +1 -1
  66. package/lib/module/formatters/number.js +1 -1
  67. package/lib/module/formatters/phone.js +1 -1
  68. package/lib/module/formatters/windowsToIanaTable.js +1 -1
  69. package/lib/module/geolocation/adapters/expoLocation.js +1 -1
  70. package/lib/module/geolocation/index.js +1 -1
  71. package/lib/module/index.js +1 -1
  72. package/lib/module/initSDK.js +1 -1
  73. package/lib/module/initUserAuth.js +1 -1
  74. package/lib/module/logger/crashlytics.js +1 -1
  75. package/lib/module/logger/index.js +1 -1
  76. package/lib/module/logger/redact.js +1 -1
  77. package/lib/module/network/index.js +1 -1
  78. package/lib/module/network/networkStatus.js +1 -1
  79. package/lib/module/permissions/calendar.js +1 -1
  80. package/lib/module/permissions/camera.js +1 -1
  81. package/lib/module/permissions/contacts.js +1 -1
  82. package/lib/module/permissions/index.js +1 -1
  83. package/lib/module/permissions/location.js +1 -1
  84. package/lib/module/permissions/mediaLibrary.js +1 -1
  85. package/lib/module/permissions/notifications.js +1 -1
  86. package/lib/module/permissions/photos.js +1 -1
  87. package/lib/module/phone/countries.js +1 -1
  88. package/lib/module/push/index.js +1 -1
  89. package/lib/module/push/push.js +1 -1
  90. package/lib/module/push/status.js +1 -1
  91. package/lib/module/push/task.js +1 -1
  92. package/lib/module/query/apiBaseQuery.js +1 -0
  93. package/lib/module/query/createAppApi.js +1 -0
  94. package/lib/module/query/index.js +1 -0
  95. package/lib/module/query/listeners.js +1 -0
  96. package/lib/module/query/paging.js +1 -0
  97. package/lib/module/query/tags.js +1 -0
  98. package/lib/module/redux/errorToastMiddleware.js +1 -0
  99. package/lib/module/redux/index.js +1 -0
  100. package/lib/module/redux/rootReducer.js +1 -0
  101. package/lib/module/redux/serializableCheck.js +1 -0
  102. package/lib/module/secureScreen/index.js +1 -1
  103. package/lib/module/share/index.js +1 -1
  104. package/lib/module/smsRetriever/index.js +1 -1
  105. package/lib/module/specs/NativeSmsRetriever.js +1 -1
  106. package/lib/module/sqlite/adapters/expo.js +1 -1
  107. package/lib/module/sqlite/index.js +1 -1
  108. package/lib/module/storage/index.js +1 -1
  109. package/lib/module/types/axios.js +1 -1
  110. package/lib/module/types/globals.d.js +1 -1
  111. package/lib/module/utils/base64.js +1 -1
  112. package/lib/module/utils/imageCompression.js +1 -1
  113. package/lib/module/utils/index.js +1 -1
  114. package/lib/module/validators/index.js +1 -1
  115. package/lib/module/versionCheck/buildNumber.js +1 -0
  116. package/lib/module/versionCheck/index.js +1 -1
  117. package/lib/typescript/commonjs/api/clientHeaders.d.ts +25 -0
  118. package/lib/typescript/commonjs/api/minAppVersion.d.ts +24 -0
  119. package/lib/typescript/commonjs/api/requestDefaults.d.ts +21 -0
  120. package/lib/typescript/commonjs/api/retry.d.ts +23 -9
  121. package/lib/typescript/commonjs/api/tokenRefresh.d.ts +14 -2
  122. package/lib/typescript/commonjs/api/userClient.d.ts +1 -1
  123. package/lib/typescript/commonjs/auth/authStore.d.ts +76 -0
  124. package/lib/typescript/commonjs/auth/index.d.ts +2 -2
  125. package/lib/typescript/commonjs/config/index.d.ts +31 -2
  126. package/lib/typescript/commonjs/errors/extractApiError.d.ts +69 -0
  127. package/lib/typescript/commonjs/errors/index.d.ts +3 -0
  128. package/lib/typescript/commonjs/formatters/currency.d.ts +22 -7
  129. package/lib/typescript/commonjs/formatters/date.d.ts +13 -13
  130. package/lib/typescript/commonjs/formatters/dateMath.d.ts +4 -2
  131. package/lib/typescript/commonjs/formatters/formatConfig.d.ts +48 -0
  132. package/lib/typescript/commonjs/formatters/house.d.ts +143 -0
  133. package/lib/typescript/commonjs/formatters/index.d.ts +4 -0
  134. package/lib/typescript/commonjs/formatters/number.d.ts +15 -5
  135. package/lib/typescript/commonjs/index.d.ts +21 -8
  136. package/lib/typescript/commonjs/initSDK.d.ts +18 -6
  137. package/lib/typescript/commonjs/initUserAuth.d.ts +29 -0
  138. package/lib/typescript/commonjs/logger/index.d.ts +17 -0
  139. package/lib/typescript/commonjs/query/apiBaseQuery.d.ts +55 -0
  140. package/lib/typescript/commonjs/query/createAppApi.d.ts +21 -0
  141. package/lib/typescript/commonjs/query/index.d.ts +9 -0
  142. package/lib/typescript/commonjs/query/listeners.d.ts +11 -0
  143. package/lib/typescript/commonjs/query/paging.d.ts +42 -0
  144. package/lib/typescript/commonjs/query/tags.d.ts +31 -0
  145. package/lib/typescript/commonjs/redux/errorToastMiddleware.d.ts +51 -0
  146. package/lib/typescript/commonjs/redux/index.d.ts +6 -0
  147. package/lib/typescript/commonjs/redux/rootReducer.d.ts +19 -0
  148. package/lib/typescript/commonjs/redux/serializableCheck.d.ts +14 -0
  149. package/lib/typescript/commonjs/versionCheck/buildNumber.d.ts +14 -0
  150. package/lib/typescript/commonjs/versionCheck/index.d.ts +28 -17
  151. package/lib/typescript/module/api/clientHeaders.d.ts +25 -0
  152. package/lib/typescript/module/api/minAppVersion.d.ts +24 -0
  153. package/lib/typescript/module/api/requestDefaults.d.ts +21 -0
  154. package/lib/typescript/module/api/retry.d.ts +23 -9
  155. package/lib/typescript/module/api/tokenRefresh.d.ts +14 -2
  156. package/lib/typescript/module/api/userClient.d.ts +1 -1
  157. package/lib/typescript/module/auth/authStore.d.ts +76 -0
  158. package/lib/typescript/module/auth/index.d.ts +2 -2
  159. package/lib/typescript/module/config/index.d.ts +31 -2
  160. package/lib/typescript/module/errors/extractApiError.d.ts +69 -0
  161. package/lib/typescript/module/errors/index.d.ts +3 -0
  162. package/lib/typescript/module/formatters/currency.d.ts +22 -7
  163. package/lib/typescript/module/formatters/date.d.ts +13 -13
  164. package/lib/typescript/module/formatters/dateMath.d.ts +4 -2
  165. package/lib/typescript/module/formatters/formatConfig.d.ts +48 -0
  166. package/lib/typescript/module/formatters/house.d.ts +143 -0
  167. package/lib/typescript/module/formatters/index.d.ts +4 -0
  168. package/lib/typescript/module/formatters/number.d.ts +15 -5
  169. package/lib/typescript/module/index.d.ts +21 -8
  170. package/lib/typescript/module/initSDK.d.ts +18 -6
  171. package/lib/typescript/module/initUserAuth.d.ts +29 -0
  172. package/lib/typescript/module/logger/index.d.ts +17 -0
  173. package/lib/typescript/module/query/apiBaseQuery.d.ts +55 -0
  174. package/lib/typescript/module/query/createAppApi.d.ts +21 -0
  175. package/lib/typescript/module/query/index.d.ts +9 -0
  176. package/lib/typescript/module/query/listeners.d.ts +11 -0
  177. package/lib/typescript/module/query/paging.d.ts +42 -0
  178. package/lib/typescript/module/query/tags.d.ts +31 -0
  179. package/lib/typescript/module/redux/errorToastMiddleware.d.ts +51 -0
  180. package/lib/typescript/module/redux/index.d.ts +6 -0
  181. package/lib/typescript/module/redux/rootReducer.d.ts +19 -0
  182. package/lib/typescript/module/redux/serializableCheck.d.ts +14 -0
  183. package/lib/typescript/module/versionCheck/buildNumber.d.ts +14 -0
  184. package/lib/typescript/module/versionCheck/index.d.ts +28 -17
  185. package/package.json +30 -2
@@ -0,0 +1,143 @@
1
+ /**
2
+ * The house formatters: DD-MMM-YYYY dates, IST by default or the viewer's own
3
+ * zone with a label, Indian digit grouping by default, money in minor units,
4
+ * and one empty placeholder. Byte-identical in @webority/mobile-core and
5
+ * @webority/web-core.
6
+ *
7
+ * Same output on Hermes and in every browser is the design constraint, so the
8
+ * text is assembled here rather than by Intl. Engines disagree on month
9
+ * abbreviations ("Sep" or "Sept"), on the space before AM/PM (a plain or a
10
+ * narrow no-break space), on zone names ("IST" or "GMT+5:30") and on which
11
+ * Intl options exist at all (Hermes has no RelativeTimeFormat and no
12
+ * trailingZeroDisplay). IST and the viewer's zone are therefore computed with
13
+ * plain Date arithmetic; Intl is used only to read the wall clock of an
14
+ * explicitly named IANA zone, through formatToParts with numeric fields, to
15
+ * read the locale's 12- or 24-hour clock, and where a caller asks for Intl
16
+ * output itself (Intl number options, `formatRelative({ intl: true })`).
17
+ *
18
+ * Called with no options (house defaults: zone IST, locale en-IN, empty "-"):
19
+ * - formatDate(v) "08-Apr-2026"; formatTime(v) "8:05 PM"; formatDateTime(v) "08-Apr-2026, 8:05 PM";
20
+ * - formatRelative(v) "5 minutes ago", "in 3 days", "just now";
21
+ * - formatNumber(v) "1,23,456.789" (Indian grouping, up to 3 decimals);
22
+ * - formatPercent(0.42) "42%"; formatMinor(15000000) "₹1,50,000.00";
23
+ * - a missing or unreadable value "-".
24
+ *
25
+ * With a configured locale (`configureFormatters({ locale })`), the words and separators come
26
+ * from Intl for that locale and the date order stays DD-MMM-YYYY. For en-IN in the viewer zone:
27
+ * "08-Sept-2026", "08:05 pm", "08-Sept-2026, 08:05 pm IST", "yesterday", "12,34,567.891",
28
+ * "₹1,50,000". For de-DE: "08-Sept-2026", "20:05", "1.234.567,891".
29
+ */
30
+ import { type NumberGrouping, type ZoneMode } from './formatConfig';
31
+ /** A date the house formatters accept; null, undefined and "" read as missing. */
32
+ export type DateValue = Date | string | number | null | undefined;
33
+ /** A zone mode, `'UTC'`, or any IANA zone name such as `'America/New_York'`. */
34
+ export type ZoneOption = ZoneMode | 'UTC' | (string & {});
35
+ export interface FormatDateOptions {
36
+ /** Overrides the configured zone mode for this call. */
37
+ zone?: ZoneOption;
38
+ /** Overrides the configured empty placeholder for this call. */
39
+ empty?: string;
40
+ }
41
+ export interface FormatTimeOptions extends FormatDateOptions {
42
+ /**
43
+ * 12 gives "8:05 PM", 24 gives "20:05". Defaults to 12 for the house text, and to the
44
+ * configured locale's own clock once a locale is configured (12 for en-IN and en-US,
45
+ * 24 for en-GB, de-DE and most of Europe).
46
+ */
47
+ hourCycle?: 12 | 24;
48
+ /**
49
+ * Append the zone label ("IST", "UTC", "GMT-4"; Intl's short zone name for a
50
+ * configured locale). Defaults to on for every zone except IST, so the viewer
51
+ * mode always says which clock it shows.
52
+ */
53
+ zoneLabel?: boolean;
54
+ }
55
+ export type FormatDateTimeOptions = FormatTimeOptions;
56
+ export interface FormatRelativeOptions {
57
+ /** The instant to measure from. Defaults to now. */
58
+ now?: Date | string | number;
59
+ empty?: string;
60
+ /**
61
+ * Intl's own phrasing ("yesterday", "in 2 days", "now") instead of the house phrase
62
+ * ("1 day ago"). Always on once a locale is configured. Intl phrases count in rounded
63
+ * years, months, days, hours, minutes and seconds, with no week unit, so 36 hours ahead reads
64
+ * "in 2 days". An engine without Intl.RelativeTimeFormat (older Hermes) prints the house phrase.
65
+ */
66
+ intl?: boolean;
67
+ }
68
+ /**
69
+ * The house keys, plus any `Intl.NumberFormatOptions`. With house keys only, the text is
70
+ * assembled here (same on every engine). With any other Intl key (`style`, `unit`,
71
+ * `notation`, `signDisplay`, `useGrouping`, ...), the number goes to `Intl.NumberFormat` in
72
+ * `locale` with every option passed through, so it reads as that engine's Intl reads it.
73
+ */
74
+ export interface FormatNumberOptions extends Intl.NumberFormatOptions {
75
+ /**
76
+ * Defaults to the locale's grouping (Indian for en-IN). An explicit `'indian'` or
77
+ * `'international'` prints the house text even with a configured locale; `'none'` drops
78
+ * the separators either way.
79
+ */
80
+ grouping?: NumberGrouping;
81
+ /** Defaults to 0. */
82
+ minimumFractionDigits?: number;
83
+ /** Defaults to 3 for formatNumber and 0 for formatPercent. */
84
+ maximumFractionDigits?: number;
85
+ /** Overrides the configured locale for this call. */
86
+ locale?: string;
87
+ empty?: string;
88
+ }
89
+ export interface FormatPercentOptions extends FormatNumberOptions {
90
+ /** `'ratio'` (the default) reads 0.42 as 42%; `'percent'` reads 42 as 42%. */
91
+ scale?: 'ratio' | 'percent';
92
+ }
93
+ export interface FormatMinorOptions {
94
+ /** ISO 4217 code. Defaults to `'INR'`. */
95
+ currency?: string;
96
+ /** Defaults to Indian grouping for INR and international grouping for every other currency. */
97
+ grouping?: NumberGrouping;
98
+ /** Print a whole amount without its zero decimals: "₹1,500" instead of "₹1,500.00". */
99
+ dropZeroDecimals?: boolean;
100
+ /** `false` prints the digits alone, for a field that draws the symbol itself. */
101
+ symbol?: boolean;
102
+ empty?: string;
103
+ }
104
+ /**
105
+ * "08-Apr-2026". A bare calendar date ("2026-04-08") always shows as that day;
106
+ * an instant shows its day in the configured zone.
107
+ */
108
+ export declare const formatDate: (value: DateValue, options?: FormatDateOptions) => string;
109
+ /** "8:05 PM" in IST, "8:05 PM GMT-4" in the viewer's zone; "20:05" for a configured locale with a 24-hour clock. */
110
+ export declare const formatTime: (value: DateValue, options?: FormatTimeOptions) => string;
111
+ /** "08-Apr-2026, 8:05 PM" in IST, "08-Apr-2026, 10:35 AM GMT-4" in the viewer's zone. */
112
+ export declare const formatDateTime: (value: DateValue, options?: FormatDateTimeOptions) => string;
113
+ /**
114
+ * "just now", "5 minutes ago", "in 3 days". English on every engine: Hermes
115
+ * has no Intl.RelativeTimeFormat. Counts are whole units, rounded down, so
116
+ * 59 minutes never reads as "60 minutes". With a configured locale, or
117
+ * `{ intl: true }`, the phrase is Intl's in that locale instead, with numeric
118
+ * "auto" and rounded counts: "yesterday", "in 2 days" at 36 hours ahead, "10 days ago",
119
+ * "30 seconds ago", "now".
120
+ */
121
+ export declare const formatRelative: (value: DateValue, options?: FormatRelativeOptions) => string;
122
+ /**
123
+ * "1,23,456.79" by default; a string holding a number is read as that number. Any Intl option
124
+ * beyond the house keys (`{ style: 'unit', unit: 'meter' }`, `{ notation: 'compact' }`) hands
125
+ * the number to Intl.NumberFormat with every option passed through. With a configured locale,
126
+ * the separators are that locale's ("1.234,5" for de-DE).
127
+ */
128
+ export declare const formatNumber: (value: number | string | null | undefined, options?: FormatNumberOptions) => string;
129
+ /**
130
+ * "42%" from 0.42, or from 42 with `scale: 'percent'`. Whole percent unless fraction digits are asked for.
131
+ * Any Intl option beyond the house keys goes to Intl.NumberFormat with `style: 'percent'`.
132
+ */
133
+ export declare const formatPercent: (value: number | string | null | undefined, options?: FormatPercentOptions) => string;
134
+ /**
135
+ * Money held in minor units (paise, cents), which is how every API carries
136
+ * it: formatMinor(15000000) gives "₹1,50,000.00". The split into whole and
137
+ * fractional units is done on the integer's digits, so no floating-point
138
+ * division can shift a paisa. A fractional input is rounded to the nearest
139
+ * minor unit. A currency without a known symbol prints its code: "AED 1,000.00".
140
+ * With a configured locale, Intl writes it in that locale ("150.000,00 €" for de-DE).
141
+ */
142
+ export declare const formatMinor: (amountMinor: number | string | null | undefined, options?: FormatMinorOptions) => string;
143
+ //# sourceMappingURL=house.d.ts.map
@@ -3,6 +3,10 @@ export { formatCurrency } from './currency';
3
3
  export type { DateInput, DateStyle, TimeStyle } from './date';
4
4
  export { formatDate, formatDateTime, formatRelativeTime, formatTime } from './date';
5
5
  export { addDays, diffMs, formatDateDDMMMYYYY, formatDateISO, formatDatePattern, formatTime12h, formatTimeInWindowsZone, formatTimeInZone, isDateAfter, isDateBefore, isSameDay, startOfDay } from './dateMath';
6
+ export type { FormatterConfig, NumberGrouping, ZoneMode } from './formatConfig';
7
+ export { configureFormatters, getFormatterConfig } from './formatConfig';
8
+ export type { DateValue, FormatDateOptions, FormatDateTimeOptions, FormatMinorOptions, FormatNumberOptions, FormatPercentOptions, FormatRelativeOptions, FormatTimeOptions, ZoneOption } from './house';
9
+ export { formatMinor, formatRelative } from './house';
6
10
  export { getInitials } from './initials';
7
11
  export { formatCompactNumber, formatNumber, formatPercent } from './number';
8
12
  export type { FormatPhoneOptions, PhoneCountry, PhoneCountryEntry, PhoneNumber, PhoneNumberType, PhoneParts, PhoneValidationKind } from './phone';
@@ -1,12 +1,22 @@
1
+ import { type FormatNumberOptions, type FormatPercentOptions } from './house';
1
2
  /**
2
- * Locale-aware number formatter. Defaults to `'en-IN'` (Indian grouping).
3
+ * Two forms share each name. With an options object, or nothing, the house
4
+ * formatter runs (`./house`: no Intl, the configured grouping and empty
5
+ * placeholder, a numeric string read as its number). With positional
6
+ * arguments the original Intl formatter runs, unchanged, returning '' for
7
+ * missing input.
3
8
  */
4
- export declare const formatNumber: (value: number | null | undefined, fractionDigits?: number, locale?: string) => string;
9
+ /** "1,23,456.79": the configured grouping, up to three decimals by default. */
10
+ export declare function formatNumber(value: number | string | null | undefined, options?: FormatNumberOptions): string;
11
+ /** Intl output for `locale` (default `'en-IN'`), with exactly `fractionDigits` decimals when given. */
12
+ export declare function formatNumber(value: number | null | undefined, fractionDigits: number | undefined, locale?: string): string;
13
+ /** "42%" from 0.42 (or from 42 with `scale: 'percent'`), whole percent by default. */
14
+ export declare function formatPercent(value: number | string | null | undefined, options?: FormatPercentOptions): string;
5
15
  /**
6
- * Format a 0–1 ratio (or 0–100 percent) as a percent string.
7
- * Pass `asRatio: false` if your input is already on the 0–100 scale.
16
+ * Intl percent output. Pass `asRatio: false` if the input is already on the
17
+ * 0–100 scale.
8
18
  */
9
- export declare const formatPercent: (value: number | null | undefined, fractionDigits?: number, asRatio?: boolean, locale?: string) => string;
19
+ export declare function formatPercent(value: number | null | undefined, fractionDigits: number | undefined, asRatio?: boolean, locale?: string): string;
10
20
  /**
11
21
  * Format a number compactly (1.2K, 3.4M, 1.5L, 2.3Cr).
12
22
  * Defaults to Indian compact notation via `'en-IN'` locale (lakh / crore).
@@ -13,6 +13,12 @@
13
13
  * @webority/mobile-core/share expo-sharing
14
14
  * @webority/mobile-core/secureScreen expo-screen-capture
15
15
  * @webority/mobile-core/smsRetriever Android only, own TurboModule
16
+ * @webority/mobile-core/query RTK Query base query and createApi preset
17
+ * (@reduxjs/toolkit and react-redux)
18
+ *
19
+ * `@webority/mobile-core/redux` (errorToastMiddleware, createRootReducer, resetState,
20
+ * SERIALIZABLE_IGNORED_ACTION_PATHS) is separate too: it needs @reduxjs/toolkit, an optional
21
+ * peer.
16
22
  *
17
23
  * One more path is separate for size, not for a native package:
18
24
  *
@@ -22,28 +28,35 @@
22
28
  * client reads the bearer token. It needs no optional peer: the backend is
23
29
  * expo-secure-store, and `expo` is required anyway.
24
30
  */
31
+ export type { AccountIdProvider, ClientKind } from './api/clientHeaders';
32
+ export { ACCOUNT_ID_HEADER, CLIENT_BUILD_HEADER, CLIENT_KIND, CLIENT_KIND_HEADER, getClientBuild } from './api/clientHeaders';
25
33
  export { buildCurl, logCurl } from './api/curl';
34
+ export type { MinAppVersionListener } from './api/minAppVersion';
35
+ export { addMinAppVersionListener, getMinAppVersion, MIN_APP_VERSION_HEADER } from './api/minAppVersion';
26
36
  export { default as publicClient } from './api/publicClient';
37
+ export { applyRequestDefaults, newCorrelationId } from './api/requestDefaults';
27
38
  export type { RetryPolicy } from './api/retry';
28
- export { attachRetry, isRetryableStatus } from './api/retry';
39
+ export { attachRetry, IDEMPOTENCY_KEY_HEADER, isNeverSentError, isRetryableFailure, isRetryableStatus, retryAfterMs } from './api/retry';
29
40
  export { refreshAccessToken } from './api/tokenRefresh';
30
41
  export type { RefreshableStore, SessionTerminationCode } from './api/userClient';
31
- export { default as userClient, injectStore, injectUserAuth, RequestOfflineError, resetRefreshState, SESSION_TERMINATION_CODES } from './api/userClient';
32
- export type { KeychainLike, SecureCredentials, StoredToken } from './auth/authStore';
33
- export { ACCESS_TOKEN_KEY, getToken, REFRESH_TOKEN_KEY, removeToken, setKeychainImplementation, storeToken } from './auth/authStore';
42
+ export { default as userClient, injectStore, injectUserAuth, RequestOfflineError, resetRefreshState, SESSION_TERMINATION_CODES, SIGN_OUT_REASON_HEADER } from './api/userClient';
43
+ export type { KeychainLike, LegacyTokenKeys, SecureCredentials, SessionEndDetail, SessionEndedListener, SessionEndReason, StoredToken } from './auth/authStore';
44
+ 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';
34
45
  export type { JwtClaims } from './auth/jwt';
35
46
  export { decodeJWT, getJWTExpiry, isJWTExpired } from './auth/jwt';
36
47
  export type { Config, Environment, LogLevel } from './config';
37
48
  export { getConfig, getConfigValue, resetConfig, setConfig } from './config';
38
49
  export type { DeepLinkConfig, DeepLinkRoute, ParsedLink } from './deepLink';
39
50
  export { DeepLink, parseDeepLink, useDeepLink } from './deepLink';
40
- export type { DateInput, DateStyle, FormatCurrencyOptions, FormatPhoneOptions, PhoneCountry, PhoneCountryEntry, PhoneNumber, PhoneNumberType, PhoneParts, PhoneValidationKind, TimeStyle } from './formatters';
41
- export { AsYouType, addDays, clampNationalNumber, countryFlagEmoji, detectPhoneCountry, diffMs, formatCompactNumber, formatCurrency, formatDate, formatDateDDMMMYYYY, formatDateISO, formatDatePattern, formatDateTime, formatNumber, formatPercent, formatPhone, formatPhoneAsTyped, formatRelativeTime, formatTime, formatTime12h, formatTimeInWindowsZone, formatTimeInZone, getCountries, getCountryCallingCode, getInitials, getPhoneCountries, isDateAfter, isDateBefore, isSameDay, isSupportedCountry, isValidNationalNumber, isValidPhoneNumber, maxNationalNumberLength, normalizePhone, parsePhoneNumber, parsePhoneNumberFromString, splitPhoneNumber, startOfDay, validatePhoneNumberLength } from './formatters';
51
+ export type { ApiError } from './errors';
52
+ export { apiErrorMessage, CONTRACT_ERROR_CODE, extractApiError, isApiError, isNoResponse, NETWORK_CODE, OFFLINE_MESSAGE, REQUEST_CANCELED_CODE, SERVER_FAILURE_MESSAGE, TIMEOUT_CODE, TIMEOUT_MESSAGE, toFieldPath, UNEXPECTED_MESSAGE } from './errors';
53
+ export type { DateInput, DateStyle, DateValue, FormatCurrencyOptions, FormatDateOptions, FormatDateTimeOptions, FormatMinorOptions, FormatNumberOptions, FormatPercentOptions, FormatPhoneOptions, FormatRelativeOptions, FormatTimeOptions, FormatterConfig, NumberGrouping, PhoneCountry, PhoneCountryEntry, PhoneNumber, PhoneNumberType, PhoneParts, PhoneValidationKind, TimeStyle, ZoneMode, ZoneOption } from './formatters';
54
+ 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';
42
55
  export type { InitConfig } from './initSDK';
43
56
  export { initWebority } from './initSDK';
44
57
  export type { TokenRefreshConfig, TokenRefreshResult, UserAuthOptions } from './initUserAuth';
45
58
  export { initUserAuth } from './initUserAuth';
46
- export type { DeviceContext, LoggerOptions, LoggerType, RemoteLogger } from './logger';
59
+ export type { DeviceContext, LoggerOptions, LoggerType, RemoteLogger, RequestFailedContext } from './logger';
47
60
  export { configureLogger, getDeviceContext, Logger, setDeviceContext, setRemoteLogger } from './logger';
48
61
  export type { CrashlyticsModule } from './logger/crashlytics';
49
62
  export { crashlyticsRemoteLogger } from './logger/crashlytics';
@@ -57,5 +70,5 @@ export { encodeBase64 } from './utils/base64';
57
70
  export type { PasswordRules } from './validators';
58
71
  export { isAadhaar, isAlphanumeric, isBetween, isEmail, isGstin, isHexColor, isIfsc, isIndianMobile, isIndianPincode, isInteger, isNonEmpty, isNumeric, isPan, isPhone, isStrongPassword, isUrl, maxLength, minLength } from './validators';
59
72
  export type { DeviceInfoLike, ParsedVersion, Platform, UpdateInfo, UpdateType, VersionCheckResult, VersionCheckType, VersionComparison, VersionData } from './versionCheck';
60
- export { setDeviceInfoImplementation, useVersionCheck, VersionCheck } from './versionCheck';
73
+ export { isBuildBelowMinimum, parseBuildNumber, setDeviceInfoImplementation, useVersionCheck, VersionCheck } from './versionCheck';
61
74
  //# sourceMappingURL=index.d.ts.map
@@ -16,23 +16,35 @@ export interface InitConfig {
16
16
  /** Environment. Defaults to `'Development'`. */
17
17
  environment?: Environment;
18
18
  /**
19
- * ISO 3166-1 alpha-2 country code (lowercase) used for App Store / Play Store
20
- * version checks. Defaults to `'in'`.
19
+ * ISO 3166-1 alpha-2 country code (lowercase) used in the App Store / Play
20
+ * Store link of the update prompt. Defaults to `'in'`.
21
21
  */
22
22
  country?: string;
23
23
  /**
24
- * The app's store identifier (Android package name / iOS bundle id) and its
25
- * user-visible version, both needed by the version-check module. Every
26
- * Webority app already has them in `appsettings.Compiled.json`, which is why
27
- * they come from config rather than across the native bridge.
24
+ * The app's store identifier (Android package name / iOS bundle id), its
25
+ * user-visible version and its internal build number (`VERSION_INTERNAL`).
26
+ * Every Webority app already has them in `appsettings.Compiled.json`, which
27
+ * is why they come from config rather than across the native bridge. The
28
+ * version check compares `appBuild` with the API's `X-Min-App-Version`.
28
29
  */
29
30
  appId?: string;
30
31
  appVersion?: string;
32
+ appBuild?: number;
33
+ /** The numeric Apple App Store id; the iOS update button needs it. */
34
+ appStoreId?: string;
35
+ /** The build's short git sha (`COMMIT` in appsettings); sent as `X-Client-Build: <appVersion>+<commit>`. */
36
+ commit?: string;
31
37
  /**
32
38
  * Log a redacted curl line per request. Off by default; it is a debugging
33
39
  * aid, not something to leave on.
34
40
  */
35
41
  logCurl?: boolean;
42
+ /** Request timeout in milliseconds. Defaults to 30000; a request's own `timeout` wins. */
43
+ timeoutMs?: number;
44
+ /** Retries under the retry rule. Defaults to 3; 0 turns retrying off. */
45
+ retries?: number;
46
+ /** Header for the per-request correlation id. Defaults to `'X-Correlation-Id'`; `null` sends none. */
47
+ correlationIdHeader?: string | null;
36
48
  /**
37
49
  * The native modules that fill the seams the library does not import.
38
50
  *
@@ -1,3 +1,5 @@
1
+ import type { AccountIdProvider } from './api/clientHeaders';
2
+ import { type LegacyTokenKeys } from './auth/authStore';
1
3
  /** The tokens a refresh response carries, with their expiry timestamps. */
2
4
  export interface TokenRefreshResult {
3
5
  accessToken: string;
@@ -17,6 +19,12 @@ export interface TokenRefreshConfig {
17
19
  accessToken: string | null;
18
20
  refreshToken: string;
19
21
  }) => unknown;
22
+ /**
23
+ * Extra headers for the refresh call, read on every refresh; may return a promise. For a
24
+ * value the API must see as a header, such as `X-Installation-Id` for a rate limiter that
25
+ * cannot read the body.
26
+ */
27
+ headers?: () => Record<string, string> | Promise<Record<string, string>>;
20
28
  /**
21
29
  * Reads the new tokens from the response body. Defaults to the Webority API's
22
30
  * `{ accessToken, accessTokenExpiration, refreshToken, refreshTokenExpiration }`.
@@ -27,12 +35,33 @@ export interface UserAuthOptions {
27
35
  /** Action creator dispatched when the session is over. */
28
36
  logout: () => unknown;
29
37
  refresh: TokenRefreshConfig;
38
+ /**
39
+ * The account the signed-in user is working in, sent as `X-Account-Id` on
40
+ * every userClient request. Read on every send, so a switch applies at once.
41
+ * Omit it in a product whose API takes the account from the token alone.
42
+ */
43
+ accountId?: AccountIdProvider;
44
+ /**
45
+ * The response header in which the API names why it ended a session. A 401 carrying it is a
46
+ * revoked session: no refresh is tried, the session is cleared as `terminated`, and the
47
+ * value reaches every `addSessionEndedListener` listener as `detail.signOutReason`. It is
48
+ * read from a refused refresh too. Default `'X-Sign-Out-Reason'`; `null` turns it off.
49
+ */
50
+ signOutReasonHeader?: string | null;
51
+ /**
52
+ * The secure-store keys the app kept its session under before this library. The first token
53
+ * read that finds the library's keys empty moves a session found there and deletes the old
54
+ * keys, so the release that adopts the library signs nobody out.
55
+ */
56
+ legacyKeys?: LegacyTokenKeys;
30
57
  }
31
58
  /**
32
59
  * Wire the user client to the app: the Redux store it dispatches `logout` to,
33
60
  * and the refresh endpoint it calls when an access token expires or a request
34
61
  * answers 401. Only a 400 or 401 from that endpoint, or a missing or expired
35
62
  * refresh token, logs out; a network error, timeout or 5xx keeps the session.
63
+ * Logging out clears the session first (`clearSession('rejected' | 'terminated')`),
64
+ * so the tokens are gone and the session-ended listeners hear it, then dispatches `logout`.
36
65
  *
37
66
  * @example
38
67
  * initUserAuth(store, { logout, refresh: { path: '/Account/RefreshToken' } });
@@ -6,6 +6,7 @@ type LogFn = (message: string, ...optionalParams: unknown[]) => void;
6
6
  * library depend on any of them.
7
7
  *
8
8
  * Every method is optional; the library calls only what the adapter implements.
9
+ * `log` receives `info`, `warn` and `error` lines; `debug` never leaves the console.
9
10
  */
10
11
  export interface RemoteLogger {
11
12
  /** Append a breadcrumb (small, non-error event) for crash context. */
@@ -57,7 +58,21 @@ export interface LoggerOptions {
57
58
  }
58
59
  /** Configure dedupe window/threshold and screen history size. Merges with current options. */
59
60
  export declare const configureLogger: (options: LoggerOptions) => void;
61
+ /** What `Logger.requestFailed` is told about the call beside the error itself. */
62
+ export interface RequestFailedContext {
63
+ /** What the call was, in words: `'Load projects'`. Names the log line; defaults to the method and path. */
64
+ label?: string;
65
+ /**
66
+ * Statuses this call answers as part of its work (a 409 the screen explains, a 404 that
67
+ * means "none yet"): logged as a warning, never recorded as an error.
68
+ */
69
+ expectedStatuses?: readonly number[];
70
+ /** Anything else worth carrying to the remote sink. Never a token or a request body. */
71
+ [key: string]: unknown;
72
+ }
60
73
  export interface LoggerType {
74
+ /** Console only, never forwarded to the remote sink. */
75
+ debug: LogFn;
61
76
  info: LogFn;
62
77
  warn: LogFn;
63
78
  error: LogFn;
@@ -65,6 +80,8 @@ export interface LoggerType {
65
80
  breadcrumb: (message: string, data?: Record<string, unknown>) => void;
66
81
  /** Record a non-fatal error with optional context. */
67
82
  recordError: (error: unknown, context?: Record<string, unknown>) => void;
83
+ /** Log a failed service call: cancel as info, an expected status as a warning, anything else as a recorded error. */
84
+ requestFailed: (error: unknown, context?: RequestFailedContext) => void;
68
85
  /** Bind a user identity for subsequent crash reports. */
69
86
  setUser: (id: string | null, attrs?: Record<string, unknown>) => void;
70
87
  /** Attach a custom attribute (release, build, env, role, etc.). */
@@ -0,0 +1,55 @@
1
+ import type { BaseQueryFn } from '@reduxjs/toolkit/query';
2
+ import { type AxiosInstance, type Method, type ResponseType } from 'axios';
3
+ import { type ApiError } from '../errors';
4
+ /**
5
+ * What an endpoint's `query` returns. A bare string is a GET of that URL.
6
+ *
7
+ * `silent` opts this call out of the error toast (decision 42); an endpoint can
8
+ * instead set it once for every call with `extraOptions: { silent: true }`.
9
+ * `public` sends the call through the anonymous client (sign-in, sign-up, a
10
+ * public lookup), so one `createApi` serves both clients.
11
+ */
12
+ export interface ApiRequest {
13
+ url: string;
14
+ method?: Method;
15
+ /** The request body. FormData is sent as multipart by the client. */
16
+ data?: unknown;
17
+ /** Query string values; build list queries with `buildListQuery`. */
18
+ params?: Record<string, unknown>;
19
+ headers?: Record<string, string>;
20
+ /** Only JSON-safe types belong in the store; a blob download stays a service call. */
21
+ responseType?: Extract<ResponseType, 'json' | 'text'>;
22
+ timeout?: number;
23
+ silent?: boolean;
24
+ public?: boolean;
25
+ }
26
+ export type ApiQueryArgs = string | ApiRequest;
27
+ /** Per-endpoint options, set as the endpoint's `extraOptions`. */
28
+ export interface ApiExtraOptions {
29
+ silent?: boolean;
30
+ }
31
+ /**
32
+ * Returned as the base query's `meta`, which RTK Query copies onto the
33
+ * fulfilled and rejected actions as `action.meta.baseQueryMeta`. The toast
34
+ * middleware reads `silent` there. Plain values only, so the store stays
35
+ * serializable.
36
+ */
37
+ export interface ApiBaseQueryMeta {
38
+ silent: boolean;
39
+ /** The HTTP status, or 0 when no response arrived. */
40
+ status: number;
41
+ }
42
+ export interface ApiBaseQueryOptions {
43
+ /** The signed-in client every call uses by default (`userClient`). */
44
+ client: AxiosInstance;
45
+ /** The anonymous client for calls marked `public: true` (`publicClient`). */
46
+ publicClient?: AxiosInstance;
47
+ }
48
+ export type ApiBaseQuery = BaseQueryFn<ApiQueryArgs, unknown, ApiError, ApiExtraOptions, ApiBaseQueryMeta>;
49
+ /**
50
+ * The fleet RTK Query base query: every call goes through our axios clients,
51
+ * so refresh, retry, the offline check and logging stay in one place, and a
52
+ * failure comes back as the same `ApiError` a thunk rejects with.
53
+ */
54
+ export declare const createApiBaseQuery: ({ client, publicClient }: ApiBaseQueryOptions) => ApiBaseQuery;
55
+ //# sourceMappingURL=apiBaseQuery.d.ts.map
@@ -0,0 +1,21 @@
1
+ import { createApi } from '@reduxjs/toolkit/query/react';
2
+ /**
3
+ * The fleet `createApi` defaults. Unused data is kept a minute, and active
4
+ * queries refetch when the connection returns and when the user comes back to
5
+ * the app. Both flags only act once the app calls `setupApiListeners` on its
6
+ * store: window focus and online events on the web, `AppState` and the
7
+ * network status on a device.
8
+ */
9
+ export declare const APP_API_DEFAULTS: {
10
+ readonly keepUnusedDataFor: 60;
11
+ readonly refetchOnReconnect: true;
12
+ readonly refetchOnFocus: true;
13
+ };
14
+ /**
15
+ * `createApi` with the fleet defaults; anything the app passes wins. One per
16
+ * app, in `services/api/apiSlice`, with `baseQuery: createApiBaseQuery(...)`
17
+ * and the app's `tagTypes`. Imported from the React entry so endpoints get
18
+ * their hooks; that entry needs `react-redux`, which every app has.
19
+ */
20
+ export declare const createAppApi: typeof createApi;
21
+ //# sourceMappingURL=createAppApi.d.ts.map
@@ -0,0 +1,9 @@
1
+ export type { ApiBaseQuery, ApiBaseQueryMeta, ApiBaseQueryOptions, ApiExtraOptions, ApiQueryArgs, ApiRequest } from './apiBaseQuery';
2
+ export { createApiBaseQuery } from './apiBaseQuery';
3
+ export { APP_API_DEFAULTS, createAppApi } from './createAppApi';
4
+ export { setupApiListeners } from './listeners';
5
+ export type { ListFilterValue, ListQuery, PagedDataObject, PagedListRequest, SortOrder } from './paging';
6
+ export { buildListQuery, getNextPageParam, getPreviousPageParam, hasNextPage, hasPreviousPage } from './paging';
7
+ export type { ApiTag, TagId } from './tags';
8
+ export { itemTag, LIST_TAG_ID, listTag, providesList, providesPagedList } from './tags';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,11 @@
1
+ import type { ThunkDispatch, UnknownAction } from '@reduxjs/toolkit';
2
+ /**
3
+ * Wires `refetchOnFocus` and `refetchOnReconnect` to the device. RTK's default
4
+ * handlers listen to `window` focus and online events, which never fire in
5
+ * React Native, so the app returning to the foreground counts as focus and
6
+ * mobile-core's network status drives online and offline (the same status the
7
+ * user client checks before every request). Call once after the store is
8
+ * created; it returns the unsubscribe.
9
+ */
10
+ export declare const setupApiListeners: (dispatch: ThunkDispatch<unknown, unknown, UnknownAction>) => (() => void);
11
+ //# sourceMappingURL=listeners.d.ts.map
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The fleet list contract, matching Webority.Delivery: the request is
3
+ * `PagedListRequest` (`page` 1-based, `pageSize`, `sortBy`, `sortOrder`) plus the
4
+ * endpoint's filters, and the response is `PagedDataObject<T>`. The server
5
+ * defaults a missing page to 1 and a missing size to 20, and cuts a size over
6
+ * 100 to 100.
7
+ */
8
+ export interface PagedDataObject<T> {
9
+ items: T[];
10
+ page: number;
11
+ pageSize: number;
12
+ totalCount: number;
13
+ totalPages: number;
14
+ }
15
+ export type SortOrder = 'asc' | 'desc';
16
+ export interface PagedListRequest {
17
+ page?: number;
18
+ pageSize?: number;
19
+ sortBy?: string;
20
+ sortOrder?: SortOrder;
21
+ }
22
+ export type ListFilterValue = string | number | boolean | null | undefined;
23
+ export interface ListQuery extends PagedListRequest {
24
+ filters?: Record<string, ListFilterValue>;
25
+ }
26
+ /**
27
+ * The `params` for a list endpoint. Filters sit beside the paging keys, as the
28
+ * API's request type derives from `PagedListRequest`. Unset values and empty
29
+ * strings are dropped, so a cleared filter never sends `?status=`. A filter
30
+ * named like a paging key is refused rather than silently overriding it.
31
+ */
32
+ export declare const buildListQuery: ({ page, pageSize, sortBy, sortOrder, filters }: ListQuery) => Record<string, string | number | boolean>;
33
+ export declare const hasNextPage: (page: PagedDataObject<unknown>) => boolean;
34
+ export declare const hasPreviousPage: (page: PagedDataObject<unknown>) => boolean;
35
+ /**
36
+ * `getNextPageParam` for an RTK Query infinite query over a paged endpoint
37
+ * (pull-to-load lists): the next page number, or `undefined` on the last page.
38
+ */
39
+ export declare const getNextPageParam: (lastPage: PagedDataObject<unknown>) => number | undefined;
40
+ /** `getPreviousPageParam` for the same infinite query. */
41
+ export declare const getPreviousPageParam: (firstPage: PagedDataObject<unknown>) => number | undefined;
42
+ //# sourceMappingURL=paging.d.ts.map
@@ -0,0 +1,31 @@
1
+ import type { PagedDataObject } from './paging';
2
+ /**
3
+ * The fleet tag convention. A list read provides `{ type, id: 'LIST' }` plus one
4
+ * tag per row; a create invalidates `LIST`, an update or delete invalidates the
5
+ * row's tag (and `LIST` when it changes membership or order). Row ids are the
6
+ * public ids the API returns (D-039), never an internal key.
7
+ */
8
+ export declare const LIST_TAG_ID = "LIST";
9
+ export type TagId = string | number;
10
+ export interface ApiTag<TagType extends string> {
11
+ type: TagType;
12
+ id: TagId;
13
+ }
14
+ type IdSelector<T> = (item: T) => TagId;
15
+ export declare const listTag: <TagType extends string>(type: TagType) => ApiTag<TagType>;
16
+ export declare const itemTag: <TagType extends string>(type: TagType, id: TagId) => ApiTag<TagType>;
17
+ /** Tags for a list response. A failed read still provides `LIST`, so the next write refetches it. */
18
+ export declare function providesList<TagType extends string, T extends {
19
+ publicId: string;
20
+ }>(type: TagType, items: readonly T[] | undefined): ApiTag<TagType>[];
21
+ export declare function providesList<TagType extends string, T>(type: TagType, items: readonly T[] | undefined, selectId: IdSelector<T>): ApiTag<TagType>[];
22
+ /**
23
+ * `providesTags` for an endpoint returning `PagedDataObject<T>`:
24
+ * `providesTags: providesPagedList('Project')`.
25
+ */
26
+ export declare function providesPagedList<TagType extends string, T extends {
27
+ publicId: string;
28
+ }>(type: TagType): (result: PagedDataObject<T> | undefined) => ApiTag<TagType>[];
29
+ export declare function providesPagedList<TagType extends string, T>(type: TagType, selectId: IdSelector<T>): (result: PagedDataObject<T> | undefined) => ApiTag<TagType>[];
30
+ export {};
31
+ //# sourceMappingURL=tags.d.ts.map
@@ -0,0 +1,51 @@
1
+ import type { Middleware, MiddlewareAPI, UnknownAction } from '@reduxjs/toolkit';
2
+ import { type ApiError } from '../errors/extractApiError';
3
+ /**
4
+ * Toasts every rejected thunk and every failed RTK Query call, so no screen has to remember
5
+ * to surface a failure and none words it differently. Identical source in web-core and
6
+ * mobile-core; the toast itself comes in through `showToast`, so there is no UI dependency.
7
+ *
8
+ * Opt out with `silent: true` (decision 42), wherever the caller can put it:
9
+ * - a thunk: `rejectWithValue(extractApiError(e), { silent: true })`, or `{ silent: true }`
10
+ * in the thunk's object argument;
11
+ * - an RTK Query call: `{ silent: true }` in the call's argument object;
12
+ * - an RTK Query endpoint: `extraOptions: { silent: true }`, which the base query copies
13
+ * onto its meta.
14
+ *
15
+ * Never toasted: an aborted thunk or a cancelled request (a screen unmounting), an RTK Query
16
+ * condition skip (the data is already cached), a 401 by default (the auth layer owns a dead
17
+ * session). Identical messages are de-duplicated for `dedupeMs`, because a screen that fires
18
+ * four fetches and loses the network would otherwise stack four copies of one sentence.
19
+ *
20
+ * `onRejected` is the product's say over one rejection, run before the default rules:
21
+ * `'toast'` shows it even where `ignoreCodes` or `ignoreStatuses` would not (a 401 that names a
22
+ * code is a refused sign-in, not a dead session), `'silent'` drops it, and nothing at all leaves
23
+ * the default rules to decide. It runs for silent rejections too, so a side effect (a
24
+ * read-only workspace notice, a profile refetch) fires whichever screen asked; `silent: true`
25
+ * still keeps the default toast off, because the screen said it answers the failure itself.
26
+ */
27
+ export type ShowErrorToast = (message: string, error: ApiError) => void;
28
+ /** What `onRejected` decides for one rejection: `'toast'`, `'silent'`, or nothing for the default rules. */
29
+ export type RejectionDecision = 'toast' | 'silent' | undefined;
30
+ /**
31
+ * The product's hook into every rejection the middleware sees. `api` is the store's
32
+ * `dispatch` and `getState`, for a side effect that reads or updates state.
33
+ */
34
+ export type OnRejected = (action: UnknownAction, error: ApiError, api: MiddlewareAPI) => RejectionDecision;
35
+ export interface ErrorToastOptions {
36
+ showToast: ShowErrorToast;
37
+ /** Server `code` values a screen answers in its own way (a paywall, a terms gate). */
38
+ ignoreCodes?: readonly string[];
39
+ /** HTTP statuses never toasted. Default `[401]`. */
40
+ ignoreStatuses?: readonly number[];
41
+ /** Window in which an identical message is shown once. Default 4000 ms; 0 disables. */
42
+ dedupeMs?: number;
43
+ /** Decides one rejection before the default rules; see the module comment. */
44
+ onRejected?: OnRejected;
45
+ }
46
+ type Dict = Record<string, unknown>;
47
+ /** Is this a rejected createAsyncThunk or RTK Query action that asked not to be toasted? */
48
+ export declare const isSilentRejection: (meta: Dict) => boolean;
49
+ export declare function errorToastMiddleware(options: ErrorToastOptions): Middleware;
50
+ export {};
51
+ //# sourceMappingURL=errorToastMiddleware.d.ts.map
@@ -0,0 +1,6 @@
1
+ export type { ErrorToastOptions, OnRejected, RejectionDecision, ShowErrorToast } from './errorToastMiddleware';
2
+ export { errorToastMiddleware, isSilentRejection } from './errorToastMiddleware';
3
+ export type { RootReducerOptions } from './rootReducer';
4
+ export { createRootReducer, resetState } from './rootReducer';
5
+ export { SERIALIZABLE_IGNORED_ACTION_PATHS } from './serializableCheck';
6
+ //# sourceMappingURL=index.d.ts.map