@tma.js/sdk 1.4.4 → 1.4.7

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 (298) hide show
  1. package/README.md +2 -2
  2. package/dist/dts/bridge/env/index.d.ts +0 -1
  3. package/dist/dts/bridge/events/events.d.ts +16 -16
  4. package/dist/dts/bridge/methods/methods.d.ts +27 -27
  5. package/dist/dts/bridge/methods/popup.d.ts +1 -1
  6. package/dist/dts/index.d.ts +3 -3
  7. package/dist/dts/init-data/types.d.ts +3 -3
  8. package/dist/dts/launch-params/index.d.ts +1 -4
  9. package/dist/dts/launch-params/retrieveFromLocation.d.ts +2 -2
  10. package/dist/dts/launch-params/retrieveFromPerformance.d.ts +3 -4
  11. package/dist/dts/launch-params/retrieveFromUrl.d.ts +3 -2
  12. package/dist/dts/launch-params/retrieveLaunchData.d.ts +1 -0
  13. package/dist/dts/launch-params/retrieveLaunchParams.d.ts +6 -0
  14. package/dist/dts/launch-params/storage.d.ts +3 -5
  15. package/dist/dts/launch-params/types.d.ts +1 -1
  16. package/dist/dts/{launch-params → misc}/getFirstNavigationEntry.d.ts +1 -1
  17. package/dist/dts/misc/index.d.ts +3 -0
  18. package/dist/dts/{bridge/env → misc}/isIframe.d.ts +1 -1
  19. package/dist/dts/misc/isPageReload.d.ts +5 -0
  20. package/dist/dts/theme-params/types.d.ts +1 -1
  21. package/dist/index.cjs +1 -2
  22. package/dist/index.iife.js +1 -2
  23. package/dist/index.mjs +841 -866
  24. package/package.json +2 -3
  25. package/dist/dts/launch-params/computeLaunchData.d.ts +0 -6
  26. package/dist/dts/launch-params/computePageReload.d.ts +0 -6
  27. package/dist/dts/launch-params/retrieveCurrent.d.ts +0 -5
  28. package/dist/index.cjs.map +0 -1
  29. package/dist/index.iife.js.map +0 -1
  30. package/dist/index.mjs.map +0 -1
  31. package/src/__tests__/globals.ts +0 -39
  32. package/src/back-button/BackButton.ts +0 -90
  33. package/src/back-button/__tests__/BackButton.ts +0 -129
  34. package/src/back-button/index.ts +0 -2
  35. package/src/back-button/types.ts +0 -14
  36. package/src/bridge/__tests__/parseMessage.ts +0 -23
  37. package/src/bridge/__tests__/request.ts +0 -236
  38. package/src/bridge/env/__tests__/hasExternalNotify.ts +0 -15
  39. package/src/bridge/env/__tests__/hasWebviewProxy.ts +0 -15
  40. package/src/bridge/env/__tests__/isIframe.ts +0 -30
  41. package/src/bridge/env/hasExternalNotify.ts +0 -19
  42. package/src/bridge/env/hasWebviewProxy.ts +0 -19
  43. package/src/bridge/env/index.ts +0 -3
  44. package/src/bridge/env/isIframe.ts +0 -11
  45. package/src/bridge/errors/MethodUnsupportedError.ts +0 -13
  46. package/src/bridge/errors/ParameterUnsupportedError.ts +0 -13
  47. package/src/bridge/errors/index.ts +0 -2
  48. package/src/bridge/events/__tests__/createEmitter.ts +0 -143
  49. package/src/bridge/events/__tests__/off.ts +0 -34
  50. package/src/bridge/events/__tests__/on.ts +0 -49
  51. package/src/bridge/events/__tests__/onTelegramEvent.ts +0 -49
  52. package/src/bridge/events/__tests__/once.ts +0 -64
  53. package/src/bridge/events/__tests__/singletonEmitter.ts +0 -22
  54. package/src/bridge/events/__tests__/subscribe.ts +0 -49
  55. package/src/bridge/events/__tests__/unsubscribe.ts +0 -34
  56. package/src/bridge/events/createEmitter.ts +0 -108
  57. package/src/bridge/events/events.ts +0 -170
  58. package/src/bridge/events/index.ts +0 -9
  59. package/src/bridge/events/off.ts +0 -14
  60. package/src/bridge/events/on.ts +0 -19
  61. package/src/bridge/events/onTelegramEvent.ts +0 -81
  62. package/src/bridge/events/once.ts +0 -18
  63. package/src/bridge/events/parsers/__tests__/clipboardTextReceived.ts +0 -21
  64. package/src/bridge/events/parsers/__tests__/invoiceClosed.ts +0 -12
  65. package/src/bridge/events/parsers/__tests__/popupClosed.ts +0 -10
  66. package/src/bridge/events/parsers/__tests__/qrTextReceived.ts +0 -9
  67. package/src/bridge/events/parsers/__tests__/theme-changed.ts +0 -42
  68. package/src/bridge/events/parsers/__tests__/viewportChanged.ts +0 -49
  69. package/src/bridge/events/parsers/clipboardTextReceived.ts +0 -26
  70. package/src/bridge/events/parsers/customMethodInvoked.ts +0 -25
  71. package/src/bridge/events/parsers/index.ts +0 -9
  72. package/src/bridge/events/parsers/invoiceClosed.ts +0 -26
  73. package/src/bridge/events/parsers/phoneRequested.ts +0 -14
  74. package/src/bridge/events/parsers/popupClosed.ts +0 -19
  75. package/src/bridge/events/parsers/qrTextReceived.ts +0 -14
  76. package/src/bridge/events/parsers/theme-changed.ts +0 -58
  77. package/src/bridge/events/parsers/viewportChanged.ts +0 -33
  78. package/src/bridge/events/parsers/writeAccessRequested.ts +0 -14
  79. package/src/bridge/events/singletonEmitter.ts +0 -19
  80. package/src/bridge/events/subscribe.ts +0 -15
  81. package/src/bridge/events/unsubscribe.ts +0 -10
  82. package/src/bridge/index.ts +0 -7
  83. package/src/bridge/invokeCustomMethod.ts +0 -56
  84. package/src/bridge/methods/__tests__/createPostEvent.ts +0 -37
  85. package/src/bridge/methods/__tests__/postEvent.ts +0 -137
  86. package/src/bridge/methods/createPostEvent.ts +0 -40
  87. package/src/bridge/methods/custom-methods.ts +0 -68
  88. package/src/bridge/methods/haptic.ts +0 -52
  89. package/src/bridge/methods/index.ts +0 -6
  90. package/src/bridge/methods/methods.ts +0 -370
  91. package/src/bridge/methods/popup.ts +0 -53
  92. package/src/bridge/methods/postEvent.ts +0 -101
  93. package/src/bridge/parseMessage.ts +0 -28
  94. package/src/bridge/request.ts +0 -176
  95. package/src/classnames/__tests__/classNames.ts +0 -20
  96. package/src/classnames/__tests__/mergeClassNames.ts +0 -21
  97. package/src/classnames/classNames.ts +0 -34
  98. package/src/classnames/index.ts +0 -2
  99. package/src/classnames/mergeClassNames.ts +0 -60
  100. package/src/closing-behavior/ClosingBehavior.ts +0 -64
  101. package/src/closing-behavior/__tests__/ClosingBehavior.ts +0 -86
  102. package/src/closing-behavior/index.ts +0 -2
  103. package/src/closing-behavior/types.ts +0 -12
  104. package/src/cloud-storage/CloudStorage.ts +0 -138
  105. package/src/cloud-storage/index.ts +0 -1
  106. package/src/colors/__tests__/isColorDark.ts +0 -12
  107. package/src/colors/__tests__/isRGB.ts +0 -13
  108. package/src/colors/__tests__/isRGBShort.ts +0 -13
  109. package/src/colors/__tests__/toRGB.ts +0 -23
  110. package/src/colors/index.ts +0 -5
  111. package/src/colors/isColorDark.ts +0 -22
  112. package/src/colors/isRGB.ts +0 -9
  113. package/src/colors/isRGBShort.ts +0 -9
  114. package/src/colors/toRGB.ts +0 -49
  115. package/src/colors/types.ts +0 -9
  116. package/src/css/__tests__/bindMiniAppCSSVars.ts +0 -175
  117. package/src/css/__tests__/bindThemeCSSVars.ts +0 -52
  118. package/src/css/__tests__/bindViewportCSSVars.ts +0 -55
  119. package/src/css/__tests__/setCSSVar.ts +0 -14
  120. package/src/css/bindMiniAppCSSVars.ts +0 -51
  121. package/src/css/bindThemeCSSVars.ts +0 -31
  122. package/src/css/bindViewportCSSVars.ts +0 -36
  123. package/src/css/index.ts +0 -4
  124. package/src/css/setCSSVar.ts +0 -8
  125. package/src/event-emitter/EventEmitter.ts +0 -146
  126. package/src/event-emitter/__tests__/EventEmitter.ts +0 -145
  127. package/src/event-emitter/index.ts +0 -2
  128. package/src/event-emitter/types.ts +0 -60
  129. package/src/globals.ts +0 -38
  130. package/src/haptic-feedback/HapticFeedback.ts +0 -70
  131. package/src/haptic-feedback/__tests__/HapticFeedback.ts +0 -68
  132. package/src/haptic-feedback/index.ts +0 -1
  133. package/src/index.ts +0 -185
  134. package/src/init/catchCustomStyles.ts +0 -17
  135. package/src/init/creators/__tests__/createViewport.ts +0 -96
  136. package/src/init/creators/createBackButton.ts +0 -25
  137. package/src/init/creators/createClosingBehavior.ts +0 -24
  138. package/src/init/creators/createMainButton.ts +0 -51
  139. package/src/init/creators/createMiniApp.ts +0 -48
  140. package/src/init/creators/createRequestIdGenerator.ts +0 -13
  141. package/src/init/creators/createSettingsButton.ts +0 -25
  142. package/src/init/creators/createThemeParams.ts +0 -11
  143. package/src/init/creators/createViewport.ts +0 -94
  144. package/src/init/creators/index.ts +0 -8
  145. package/src/init/css/index.ts +0 -1
  146. package/src/init/css/processCSSVarsOption.ts +0 -55
  147. package/src/init/index.ts +0 -2
  148. package/src/init/init.ts +0 -134
  149. package/src/init/types.ts +0 -94
  150. package/src/init-data/InitData.ts +0 -96
  151. package/src/init-data/__tests__/InitData.ts +0 -98
  152. package/src/init-data/__tests__/chatParser.ts +0 -102
  153. package/src/init-data/__tests__/initDataParser.ts +0 -136
  154. package/src/init-data/__tests__/parseInitData.ts +0 -136
  155. package/src/init-data/__tests__/userParser.ts +0 -96
  156. package/src/init-data/chatParser.ts +0 -19
  157. package/src/init-data/index.ts +0 -6
  158. package/src/init-data/initDataParser.ts +0 -41
  159. package/src/init-data/parseInitData.ts +0 -10
  160. package/src/init-data/types.ts +0 -164
  161. package/src/init-data/userParser.ts +0 -45
  162. package/src/invoice/Invoice.ts +0 -123
  163. package/src/invoice/index.ts +0 -2
  164. package/src/invoice/types.ts +0 -11
  165. package/src/launch-params/__tests__/retrieveFromUrl.ts +0 -19
  166. package/src/launch-params/computeLaunchData.ts +0 -81
  167. package/src/launch-params/computePageReload.ts +0 -13
  168. package/src/launch-params/getFirstNavigationEntry.ts +0 -10
  169. package/src/launch-params/index.ts +0 -13
  170. package/src/launch-params/launchParamsParser.ts +0 -45
  171. package/src/launch-params/parseLaunchParams.ts +0 -10
  172. package/src/launch-params/retrieveCurrent.ts +0 -27
  173. package/src/launch-params/retrieveFromLocation.ts +0 -10
  174. package/src/launch-params/retrieveFromPerformance.ts +0 -18
  175. package/src/launch-params/retrieveFromUrl.ts +0 -19
  176. package/src/launch-params/retrieveLaunchData.ts +0 -30
  177. package/src/launch-params/serializeLaunchParams.ts +0 -37
  178. package/src/launch-params/storage.ts +0 -33
  179. package/src/launch-params/types.ts +0 -62
  180. package/src/logger/Logger.ts +0 -72
  181. package/src/logger/__tests__/Logger.ts +0 -107
  182. package/src/logger/index.ts +0 -1
  183. package/src/main-button/MainButton.ts +0 -239
  184. package/src/main-button/__tests__/MainButton.ts +0 -346
  185. package/src/main-button/index.ts +0 -2
  186. package/src/main-button/types.ts +0 -26
  187. package/src/mini-app/MiniApp.ts +0 -348
  188. package/src/mini-app/__tests__/MiniApp.ts +0 -140
  189. package/src/mini-app/contactParser.ts +0 -29
  190. package/src/mini-app/index.ts +0 -2
  191. package/src/mini-app/types.ts +0 -38
  192. package/src/misc/__tests__/isRecord.ts +0 -21
  193. package/src/misc/index.ts +0 -2
  194. package/src/misc/isRecord.ts +0 -7
  195. package/src/misc/isTMA.ts +0 -13
  196. package/src/navigation/HashNavigator/HashNavigator.ts +0 -220
  197. package/src/navigation/HashNavigator/__tests__/HashNavigator.ts +0 -144
  198. package/src/navigation/HashNavigator/__tests__/drop.ts +0 -42
  199. package/src/navigation/HashNavigator/__tests__/go.ts +0 -9
  200. package/src/navigation/HashNavigator/drop.ts +0 -36
  201. package/src/navigation/HashNavigator/go.ts +0 -28
  202. package/src/navigation/HashNavigator/index.ts +0 -2
  203. package/src/navigation/HashNavigator/types.ts +0 -41
  204. package/src/navigation/Navigator/Navigator.ts +0 -282
  205. package/src/navigation/Navigator/index.ts +0 -2
  206. package/src/navigation/Navigator/types.ts +0 -55
  207. package/src/navigation/ensurePrefix.ts +0 -9
  208. package/src/navigation/getHash.ts +0 -17
  209. package/src/navigation/index.ts +0 -4
  210. package/src/parsing/ArrayValueParser.ts +0 -79
  211. package/src/parsing/ParseError.ts +0 -27
  212. package/src/parsing/ParseSchemaFieldError.ts +0 -21
  213. package/src/parsing/ValueParser.ts +0 -71
  214. package/src/parsing/__tests__/ArrayValueParser.ts +0 -18
  215. package/src/parsing/__tests__/toRecord.ts +0 -10
  216. package/src/parsing/createValueParserGenerator.ts +0 -16
  217. package/src/parsing/index.ts +0 -10
  218. package/src/parsing/parseBySchema.ts +0 -65
  219. package/src/parsing/parsers/__tests__/array.ts +0 -39
  220. package/src/parsing/parsers/__tests__/boolean.ts +0 -31
  221. package/src/parsing/parsers/__tests__/date.ts +0 -25
  222. package/src/parsing/parsers/__tests__/json.ts +0 -80
  223. package/src/parsing/parsers/__tests__/number.ts +0 -23
  224. package/src/parsing/parsers/__tests__/rgb.ts +0 -22
  225. package/src/parsing/parsers/__tests__/searchParams.ts +0 -105
  226. package/src/parsing/parsers/__tests__/string.ts +0 -25
  227. package/src/parsing/parsers/array.ts +0 -9
  228. package/src/parsing/parsers/boolean.ts +0 -22
  229. package/src/parsing/parsers/date.ts +0 -11
  230. package/src/parsing/parsers/index.ts +0 -8
  231. package/src/parsing/parsers/json.ts +0 -17
  232. package/src/parsing/parsers/number.ts +0 -21
  233. package/src/parsing/parsers/rgb.ts +0 -10
  234. package/src/parsing/parsers/searchParams.ts +0 -24
  235. package/src/parsing/parsers/string.ts +0 -12
  236. package/src/parsing/toRecord.ts +0 -27
  237. package/src/parsing/types.ts +0 -32
  238. package/src/parsing/unexpectedTypeError.ts +0 -6
  239. package/src/popup/Popup.ts +0 -91
  240. package/src/popup/__tests__/Popup.ts +0 -130
  241. package/src/popup/__tests__/preparePopupParams.ts +0 -85
  242. package/src/popup/index.ts +0 -2
  243. package/src/popup/preparePopupParams.ts +0 -59
  244. package/src/popup/types.ts +0 -69
  245. package/src/qr-scanner/QRScanner.ts +0 -95
  246. package/src/qr-scanner/index.ts +0 -2
  247. package/src/qr-scanner/types.ts +0 -11
  248. package/src/settings-button/SettingsButton.ts +0 -85
  249. package/src/settings-button/index.ts +0 -2
  250. package/src/settings-button/types.ts +0 -15
  251. package/src/state/State.ts +0 -67
  252. package/src/state/index.ts +0 -2
  253. package/src/state/types.ts +0 -31
  254. package/src/storage.ts +0 -69
  255. package/src/supports/__tests__/supports.ts +0 -123
  256. package/src/supports/createSupportsFunc.ts +0 -18
  257. package/src/supports/createSupportsParamFunc.ts +0 -27
  258. package/src/supports/index.ts +0 -4
  259. package/src/supports/supports.ts +0 -84
  260. package/src/supports/types.ts +0 -1
  261. package/src/theme-params/ThemeParams.ts +0 -131
  262. package/src/theme-params/__tests__/keys.ts +0 -19
  263. package/src/theme-params/__tests__/parseThemeParams.ts +0 -29
  264. package/src/theme-params/__tests__/serializeThemeParams.ts +0 -29
  265. package/src/theme-params/__tests__/themeParamsParser.ts +0 -29
  266. package/src/theme-params/index.ts +0 -6
  267. package/src/theme-params/keys.ts +0 -24
  268. package/src/theme-params/parseThemeParams.ts +0 -10
  269. package/src/theme-params/requestThemeParams.ts +0 -13
  270. package/src/theme-params/serializeThemeParams.ts +0 -20
  271. package/src/theme-params/themeParamsParser.ts +0 -22
  272. package/src/theme-params/types.ts +0 -33
  273. package/src/timeout/TimeoutError.ts +0 -6
  274. package/src/timeout/__tests__/isTimeoutError.ts +0 -9
  275. package/src/timeout/__tests__/withTimeout.ts +0 -28
  276. package/src/timeout/index.ts +0 -4
  277. package/src/timeout/isTimeoutError.ts +0 -9
  278. package/src/timeout/sleep.ts +0 -10
  279. package/src/timeout/withTimeout.ts +0 -24
  280. package/src/types/index.ts +0 -4
  281. package/src/types/methods.ts +0 -18
  282. package/src/types/platform.ts +0 -14
  283. package/src/types/request-id.ts +0 -10
  284. package/src/types/utils.ts +0 -50
  285. package/src/utils/Utils.ts +0 -107
  286. package/src/utils/index.ts +0 -1
  287. package/src/version/__tests__/compareVersions.ts +0 -19
  288. package/src/version/compareVersions.ts +0 -28
  289. package/src/version/index.ts +0 -2
  290. package/src/version/types.ts +0 -4
  291. package/src/viewport/Viewport.ts +0 -171
  292. package/src/viewport/__tests__/isStableViewportPlatform.ts +0 -15
  293. package/src/viewport/__tests__/utils.ts +0 -12
  294. package/src/viewport/index.ts +0 -4
  295. package/src/viewport/isStableViewportPlatform.ts +0 -10
  296. package/src/viewport/requestViewport.ts +0 -23
  297. package/src/viewport/types.ts +0 -23
  298. package/src/viewport/utils.ts +0 -7
@@ -1,282 +0,0 @@
1
- import { Logger } from '~/logger/index.js';
2
-
3
- import type {
4
- AnyEntry,
5
- NavigationEntry,
6
- NavigatorConEntry,
7
- NavigatorOptions,
8
- PerformGoOptions,
9
- PerformPushOptions,
10
- PerformReplaceOptions,
11
- } from './types.js';
12
- import { ensurePrefix } from '../ensurePrefix.js';
13
-
14
- /**
15
- * Represents basic navigator implementation which uses only memory to store and control
16
- * navigation state.
17
- */
18
- export abstract class Navigator<T> {
19
- protected logger: Logger;
20
-
21
- protected readonly entries: NavigationEntry[];
22
-
23
- constructor(
24
- entries: NavigatorConEntry[],
25
- protected entriesCursor: number,
26
- {
27
- debug = false,
28
- loggerPrefix = 'Navigator',
29
- }: NavigatorOptions,
30
- ) {
31
- if (entries.length === 0) {
32
- throw new Error('Entries list should not be empty.');
33
- }
34
-
35
- if (entriesCursor >= entries.length) {
36
- throw new Error('Cursor should be less than entries count.');
37
- }
38
-
39
- this.entries = entries.map(({ pathname = '', search, hash }) => {
40
- if (!pathname.startsWith('/') && pathname.length > 0) {
41
- throw new Error('Pathname should start with "/"');
42
- }
43
-
44
- return {
45
- pathname: ensurePrefix(pathname, '/'),
46
- search: search ? ensurePrefix(search, '?') : '',
47
- hash: hash ? ensurePrefix(hash, '#') : '',
48
- };
49
- });
50
- this.logger = new Logger(`[${loggerPrefix}]`, debug);
51
- }
52
-
53
- protected abstract performGo(options: PerformGoOptions): T;
54
-
55
- protected abstract performPush(options: PerformPushOptions): T;
56
-
57
- protected abstract performReplace(options: PerformReplaceOptions): T;
58
-
59
- /**
60
- * Converts entry to the navigation entry.
61
- * @param entry - entry data
62
- */
63
- private formatEntry(entry: AnyEntry): NavigationEntry {
64
- let path: string;
65
-
66
- if (typeof entry === 'string') {
67
- path = entry;
68
- } else {
69
- const {
70
- pathname = '',
71
- search,
72
- hash,
73
- } = entry;
74
-
75
- path = pathname
76
- + (search ? ensurePrefix(search, '?') : '')
77
- + (hash ? ensurePrefix(hash, '#') : '');
78
- }
79
-
80
- const {
81
- pathname,
82
- search,
83
- hash,
84
- } = new URL(path, `https://localhost${this.path}`);
85
- return {
86
- pathname,
87
- search,
88
- hash,
89
- };
90
- }
91
-
92
- /**
93
- * Current entry.
94
- */
95
- protected get entry(): NavigationEntry {
96
- return this.entries[this.entriesCursor];
97
- }
98
-
99
- /**
100
- * Goes back in history.
101
- */
102
- back(): T {
103
- return this.go(-1);
104
- }
105
-
106
- /**
107
- * Current entries cursor.
108
- */
109
- get cursor(): number {
110
- return this.entriesCursor;
111
- }
112
-
113
- /**
114
- * True if navigator can go back.
115
- */
116
- get canGoBack(): boolean {
117
- return this.entriesCursor > 0;
118
- }
119
-
120
- /**
121
- * True if navigator can go forward.
122
- */
123
- get canGoForward(): boolean {
124
- return this.entriesCursor !== this.entries.length - 1;
125
- }
126
-
127
- /**
128
- * Goes forward in history.
129
- */
130
- forward(): T {
131
- return this.go(1);
132
- }
133
-
134
- /**
135
- * Moves entries cursor by specified delta.
136
- * @param delta - cursor delta.
137
- */
138
- go(delta: number): T {
139
- this.logger.log(`called go(${delta})`);
140
-
141
- // Cursor should be in bounds: [0, this.entries).
142
- const cursor = Math.min(
143
- this.entries.length - 1,
144
- Math.max(this.entriesCursor + delta, 0),
145
- );
146
-
147
- if (this.entriesCursor === cursor) {
148
- return this.performGo({
149
- updated: false,
150
- delta,
151
- });
152
- }
153
-
154
- const before = this.entry;
155
- this.entriesCursor = cursor;
156
- const after = this.entry;
157
-
158
- this.logger.log('State changed', { before, after });
159
-
160
- return this.performGo({
161
- updated: true,
162
- delta,
163
- before,
164
- after,
165
- });
166
- }
167
-
168
- /**
169
- * Returns copy of navigator entries.
170
- */
171
- getEntries(): NavigationEntry[] {
172
- return this.entries.map((entry) => ({ ...entry }));
173
- }
174
-
175
- /**
176
- * Current hash.
177
- * @example
178
- * "", "#", "#hash"
179
- */
180
- get hash(): string {
181
- return this.entry.hash;
182
- }
183
-
184
- /**
185
- * Pushes new entry. Method replaces all entries after the current one with the inserted.
186
- * @param entry - entry data.
187
- *
188
- * @example Pushing absolute pathname.
189
- * push("/absolute-path"); // "/absolute-path"
190
- *
191
- * @example Pushing relative pathname.
192
- * // Pushing relative path replaces N last path parts, where N is pushed pathname parts count.
193
- * // Pushing empty path is recognized as relative, but not replacing the last pathname part.
194
- * push("relative"); // "/home/root" -> "/home/relative"
195
- *
196
- * @example Pushing query parameters.
197
- * push("/absolute?my-param=1"); // "/home" -> "/absolute?my-param=1"
198
- * push("relative?my-param=1"); // "/home/root" -> "/home/relative?my-param=1"
199
- * push("?my-param=1"); // "/home" -> "/home?my-param=1"
200
- *
201
- * @example Pushing hash.
202
- * push("#my-hash"); // "/home" -> "/home#my-hash"
203
- * push("johny#my-hash"); // "/home/root" -> "/home/johny#my-hash"
204
- */
205
- push(entry: AnyEntry): T {
206
- // In case, current cursor refers not to the last one element in the history, we should
207
- // remove everything after the cursor.
208
- if (this.entriesCursor !== this.entries.length - 1) {
209
- this.entries.splice(this.entriesCursor + 1);
210
- }
211
-
212
- const formatted = this.formatEntry(entry);
213
- const before = this.entry;
214
- this.entriesCursor += 1;
215
- this.entries[this.entriesCursor] = formatted;
216
- const after = this.entry;
217
-
218
- this.logger.log('State changed', { before, after });
219
-
220
- return this.performPush({
221
- before,
222
- after,
223
- });
224
- }
225
-
226
- /**
227
- * Current full path including pathname, query parameters and hash.
228
- */
229
- get path(): string {
230
- return `${this.pathname}${this.search}${this.hash}`;
231
- }
232
-
233
- /**
234
- * Current pathname.
235
- * @example
236
- * "/", "/abc"
237
- */
238
- get pathname(): string {
239
- return this.entry.pathname;
240
- }
241
-
242
- /**
243
- * Replaces current entry. Has the same logic as `push` method.
244
- * @param entry - entry data.
245
- * @see push
246
- * @returns True if changes were done.
247
- */
248
- replace(entry: AnyEntry): T {
249
- const formattedEntry = this.formatEntry(entry);
250
- if (
251
- this.search === formattedEntry.search
252
- && this.pathname === formattedEntry.pathname
253
- && this.hash === formattedEntry.hash
254
- ) {
255
- return this.performReplace({
256
- updated: false,
257
- entry: formattedEntry,
258
- });
259
- }
260
-
261
- const before = this.entry;
262
- this.entries[this.entriesCursor] = formattedEntry;
263
- const after = this.entry;
264
-
265
- this.logger.log('State changed', { before, after });
266
-
267
- return this.performReplace({
268
- updated: true,
269
- before,
270
- after,
271
- });
272
- }
273
-
274
- /**
275
- * Current query parameters.
276
- * @example
277
- * "", "?", "?a=1"
278
- */
279
- get search(): string {
280
- return this.entry.search;
281
- }
282
- }
@@ -1,2 +0,0 @@
1
- export * from './Navigator.js';
2
- export * from './types.js';
@@ -1,55 +0,0 @@
1
- export interface NavigationEntry {
2
- pathname: string;
3
- search: string;
4
- hash: string;
5
- }
6
-
7
- export type NavigatorConEntry = Partial<NavigationEntry>;
8
-
9
- /**
10
- * Entry information is allowed to be used in `push` and `replace` Navigator methods.
11
- * Should be either path or object partially describing it.
12
- */
13
- export type AnyEntry = string | Partial<NavigationEntry>;
14
-
15
- export type PerformGoOptions =
16
- | {
17
- updated: false;
18
- delta: number;
19
- }
20
- | {
21
- updated: true;
22
- delta: number;
23
- before: NavigationEntry;
24
- after: NavigationEntry;
25
- };
26
-
27
- export interface PerformPushOptions {
28
- before: NavigationEntry;
29
- after: NavigationEntry;
30
- }
31
-
32
- export type PerformReplaceOptions =
33
- | {
34
- updated: false;
35
- entry: NavigationEntry;
36
- }
37
- | {
38
- updated: true;
39
- before: NavigationEntry;
40
- after: NavigationEntry;
41
- };
42
-
43
- export interface NavigatorOptions {
44
- /**
45
- * Should navigator display debug messages.
46
- * @default false
47
- */
48
- debug?: boolean;
49
-
50
- /**
51
- * Prefix used for logger.
52
- * @default 'Navigator'
53
- */
54
- loggerPrefix?: string;
55
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * Ensures, that specified value starts with the specified prefix. If it doesn't, function appends
3
- * prefix.
4
- * @param value - value to check.
5
- * @param prefix - prefix to add.
6
- */
7
- export function ensurePrefix(value: string, prefix: string): string {
8
- return value.startsWith(prefix) ? value : `${prefix}${value}`;
9
- }
@@ -1,17 +0,0 @@
1
- /**
2
- * Returns string after first met "#" symbol.
3
- * @param value - string to take hash part from.
4
- *
5
- * @example No hash.
6
- * getHash('/path'); // null
7
- *
8
- * @example Has hash.
9
- * getHash('/path#abc'); // 'abc'
10
- *
11
- * @example Has double hash.
12
- * getHash('/path#abc#another'); // 'abc#another'
13
- */
14
- export function getHash(value: string): string | null {
15
- const match = value.match(/#(.+)/);
16
- return match ? match[1] : null;
17
- }
@@ -1,4 +0,0 @@
1
- export * from './ensurePrefix.js';
2
- export * from './getHash.js';
3
- export * from './HashNavigator/index.js';
4
- export * from './Navigator/index.js';
@@ -1,79 +0,0 @@
1
- import type { AnyParser, Parser } from './types.js';
2
- import { unexpectedTypeError } from './unexpectedTypeError.js';
3
- import type { ParseResult, ValueParserOverrides } from './ValueParser.js';
4
- import { ValueParser } from './ValueParser.js';
5
-
6
- export type OfResult<BaseClass, ItemType, IsOptional extends boolean> = ArrayParserType<
7
- BaseClass,
8
- ItemType,
9
- IsOptional
10
- >;
11
-
12
- export interface ArrayParserOverrides<
13
- BaseClass,
14
- ItemType,
15
- IsOptional extends boolean,
16
- > extends ValueParserOverrides<BaseClass, ItemType[], IsOptional> {
17
- /**
18
- * Specifies parser for each array item.
19
- * @param parser - item parser.
20
- */
21
- of<Item>(parser: AnyParser<Item>): OfResult<BaseClass, Item, IsOptional>;
22
- }
23
-
24
- export type ArrayParserType<BaseClass, ItemType, IsOptional extends boolean> =
25
- Omit<BaseClass, keyof ArrayParserOverrides<any, any, any>>
26
- & ArrayParserOverrides<BaseClass, ItemType, IsOptional>;
27
-
28
- /**
29
- * Parses incoming value as array.
30
- * @param value - value to parse.
31
- */
32
- function parseArray(value: unknown): unknown[] {
33
- if (Array.isArray(value)) {
34
- return value;
35
- }
36
-
37
- if (typeof value === 'string') {
38
- try {
39
- const json = JSON.parse(value);
40
-
41
- if (Array.isArray(json)) {
42
- return json;
43
- }
44
- // eslint-disable-next-line no-empty
45
- } catch (e) {
46
- }
47
- }
48
- throw unexpectedTypeError();
49
- }
50
-
51
- export class ArrayValueParser<ItemType, IsOptional extends boolean>
52
- extends ValueParser<unknown[], IsOptional> {
53
- private itemParser: Parser<any>;
54
-
55
- constructor(
56
- itemParser: AnyParser<ItemType>,
57
- isOptional: IsOptional,
58
- type?: string,
59
- ) {
60
- super(parseArray, isOptional, type);
61
-
62
- this.itemParser = typeof itemParser === 'function'
63
- ? itemParser
64
- : itemParser.parse.bind(itemParser);
65
- }
66
-
67
- override parse(value: unknown): ParseResult<ItemType[], IsOptional> {
68
- const arr = super.parse(value);
69
- return arr === undefined ? arr : arr.map(this.itemParser);
70
- }
71
-
72
- of<Item>(itemParser: AnyParser<Item>): OfResult<this, Item, IsOptional> {
73
- this.itemParser = typeof itemParser === 'function'
74
- ? itemParser
75
- : itemParser.parse.bind(itemParser);
76
-
77
- return this as OfResult<this, Item, IsOptional>;
78
- }
79
- }
@@ -1,27 +0,0 @@
1
- interface Options {
2
- /**
3
- * Type name.
4
- */
5
- type?: string;
6
-
7
- /**
8
- * Original occurred error.
9
- */
10
- cause?: unknown;
11
- }
12
-
13
- /**
14
- * Error thrown in case, there was an error during parsing.
15
- */
16
- export class ParseError extends Error {
17
- /**
18
- * Parser name.
19
- */
20
- public readonly type?: string;
21
-
22
- constructor(public readonly value: unknown, { cause, type }: Options = {}) {
23
- super(`Unable to parse value${type ? ` as ${type}` : ''}`, { cause });
24
- Object.setPrototypeOf(this, ParseError.prototype);
25
- this.type = type;
26
- }
27
- }
@@ -1,21 +0,0 @@
1
- interface Options {
2
- /**
3
- * Type name.
4
- */
5
- type?: string;
6
-
7
- /**
8
- * Original occurred error.
9
- */
10
- cause?: unknown;
11
- }
12
-
13
- /**
14
- * Error thrown in case, there was an error during parse.
15
- */
16
- export class ParseSchemaFieldError extends Error {
17
- constructor(field: string, { cause, type }: Options = {}) {
18
- super(`Unable to parse field "${field}"${type ? ` as ${type}` : ''}`, { cause });
19
- Object.setPrototypeOf(this, ParseSchemaFieldError.prototype);
20
- }
21
- }
@@ -1,71 +0,0 @@
1
- import type { If } from '~/types/index.js';
2
-
3
- import { ParseError } from './ParseError.js';
4
- import type { Parser } from './types.js';
5
-
6
- /**
7
- * Result of "parse" function.
8
- */
9
- export type ParseResult<ResultType, IsOptional extends boolean> =
10
- | ResultType
11
- | If<IsOptional, undefined, never>;
12
-
13
- /**
14
- * Result of "optional" function in ValueParser.
15
- */
16
- export type OptionalResult<BaseClass, ResultType> = ValueParserType<
17
- BaseClass,
18
- ResultType,
19
- true
20
- >;
21
-
22
- export interface ValueParserOverrides<BaseClass, ResultType, IsOptional extends boolean> {
23
- /**
24
- * Parses incoming value applying parsing function passed via constructor.
25
- * @param value - value to parse.
26
- */
27
- parse(value: unknown): ParseResult<ResultType, IsOptional>;
28
-
29
- /**
30
- * Marks this parser result as optional. This makes the parser to check if passed value
31
- * is empty. If so, parser will return undefined value instead of passing it to the actual
32
- * parser.
33
- */
34
- optional(): OptionalResult<BaseClass, ResultType>;
35
- }
36
-
37
- /**
38
- * Describes generated ValueParser interface. Shortly saying, this type overrides BaseClass
39
- * properties defined in ValueParser.
40
- */
41
- export type ValueParserType<BaseClass, ResultType, IsOptional extends boolean> =
42
- Omit<BaseClass, keyof ValueParserOverrides<any, any, any>>
43
- & ValueParserOverrides<BaseClass, ResultType, IsOptional>;
44
-
45
- export class ValueParser<ResultType, IsOptional extends boolean> {
46
- constructor(
47
- protected parser: Parser<ResultType>,
48
- protected isOptional: IsOptional,
49
- protected type?: string,
50
- ) {
51
- }
52
-
53
- parse(value: unknown): ParseResult<ResultType, IsOptional> {
54
- // In case, parsing result is specified as optional, and passed value is considered as empty,
55
- // we can return undefined. Otherwise, pass to parser.
56
- if (this.isOptional && value === undefined) {
57
- return undefined as ParseResult<ResultType, IsOptional>;
58
- }
59
-
60
- try {
61
- return this.parser(value) as ParseResult<ResultType, IsOptional>;
62
- } catch (cause) {
63
- throw new ParseError(value, { type: this.type, cause });
64
- }
65
- }
66
-
67
- optional(): OptionalResult<this, ResultType> {
68
- this.isOptional = true as IsOptional;
69
- return this as OptionalResult<this, ResultType>;
70
- }
71
- }
@@ -1,18 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
-
3
- import { ArrayValueParser } from '../ArrayValueParser';
4
- import { string } from '../parsers';
5
-
6
- describe('constructor', () => {
7
- it('should apply parser value directly if it is function', () => {
8
- const parser = new ArrayValueParser(() => 'Hello!', false);
9
-
10
- expect(parser.parse(['abc'])).toStrictEqual(['Hello!']);
11
- });
12
-
13
- it('should apply parser "parse" method directly if it is ValueParser', () => {
14
- const parser = new ArrayValueParser(string(), false);
15
-
16
- expect(parser.parse(['abc'])).toStrictEqual(['abc']);
17
- });
18
- });
@@ -1,10 +0,0 @@
1
- import { expect, it } from 'vitest';
2
-
3
- import { toRecord } from '../index';
4
-
5
- it('should throw an error in case, passed value is not JSON object or not JSON object converted to string', () => {
6
- expect(() => toRecord('')).toThrow();
7
- expect(() => toRecord(true)).toThrow();
8
- expect(() => toRecord('{}')).not.toThrow();
9
- expect(() => toRecord({})).not.toThrow();
10
- });
@@ -1,16 +0,0 @@
1
- import type { Parser } from './types.js';
2
- import { ValueParser } from './ValueParser.js';
3
-
4
- export type ValueParserGenerator<T> = () => ValueParser<T, false>;
5
-
6
- /**
7
- * Creates function which generates new scalar value parser based on the specified one.
8
- * @param parser - parser to use as basic.
9
- * @param type - type name.
10
- */
11
- export function createValueParserGenerator<T>(
12
- parser: Parser<T>,
13
- type?: string,
14
- ): ValueParserGenerator<T> {
15
- return () => new ValueParser(parser, false, type);
16
- }
@@ -1,10 +0,0 @@
1
- export * from './ArrayValueParser.js';
2
- export * from './createValueParserGenerator.js';
3
- export * from './parseBySchema.js';
4
- export * from './ParseError.js';
5
- export * from './parsers/index.js';
6
- export * from './ParseSchemaFieldError.js';
7
- export * from './toRecord.js';
8
- export * from './types.js';
9
- export * from './unexpectedTypeError.js';
10
- export * from './ValueParser.js';
@@ -1,65 +0,0 @@
1
- import { ParseError } from './ParseError.js';
2
- import { ParseSchemaFieldError } from './ParseSchemaFieldError.js';
3
- import type { Parser, Schema } from './types.js';
4
-
5
- /**
6
- * Parses external value by specified schema. Functions iterates over each schema field
7
- * and uses getField function to get its value from the external source.
8
- * @param schema - object schema.
9
- * @param getField - function which gets external value by its field name.
10
- */
11
- export function parseBySchema<T>(
12
- schema: Schema<T>,
13
- getField: (field: string) => unknown,
14
- ): T {
15
- const result = {} as T;
16
-
17
- // eslint-disable-next-line guard-for-in,no-restricted-syntax
18
- for (const field in schema) {
19
- const definition = schema[field];
20
- if (!definition) {
21
- continue;
22
- }
23
-
24
- let from: string;
25
- let parser: Parser<any>;
26
-
27
- // In case, definition has "type" property, then SchemaFieldDetailed was passed.
28
- if (typeof definition === 'function' || 'parse' in definition) {
29
- // Otherwise we are working with either parser function or instance.
30
- from = field;
31
- parser = typeof definition === 'function' ? definition : definition.parse.bind(definition);
32
- } else {
33
- const { type } = definition;
34
-
35
- from = definition.from || field;
36
- parser = typeof type === 'function' ? type : type.parse.bind(type);
37
- }
38
-
39
- let parsedValue: unknown;
40
- const originalValue = getField(from);
41
-
42
- try {
43
- parsedValue = parser(originalValue);
44
- } catch (error) {
45
- // If error is not instance of ParseError, we have nothing additional to do with the error.
46
- if (!(error instanceof ParseError)) {
47
- throw new ParseSchemaFieldError(from, { cause: error });
48
- }
49
-
50
- // Otherwise, we are going to rethrow the error with extended data.
51
- throw new ParseSchemaFieldError(from, {
52
- type: error.type,
53
- cause: error,
54
- });
55
- }
56
-
57
- if (parsedValue === undefined) {
58
- continue;
59
- }
60
-
61
- (result as any)[field] = parsedValue;
62
- }
63
-
64
- return result;
65
- }