@dynamic-labs/utils 0.19.0-alpha.9 → 0.19.1

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 (102) hide show
  1. package/CHANGELOG.md +299 -0
  2. package/package.json +7 -5
  3. package/src/CancellablePromise/CancellablePromise.cjs +126 -126
  4. package/src/CancellablePromise/CancellablePromise.d.ts +54 -54
  5. package/src/CancellablePromise/CancellablePromise.js +126 -126
  6. package/src/CancellablePromise/index.d.ts +1 -1
  7. package/src/bigIntToHex/bigIntToHex.cjs +15 -0
  8. package/src/bigIntToHex/bigIntToHex.d.ts +1 -0
  9. package/src/bigIntToHex/bigIntToHex.js +11 -0
  10. package/src/bigIntToHex/index.d.ts +1 -0
  11. package/src/bufferToBase64.cjs +5 -5
  12. package/src/bufferToBase64.d.ts +1 -1
  13. package/src/bufferToBase64.js +5 -5
  14. package/src/errors/AccountExistsError.cjs +6 -6
  15. package/src/errors/AccountExistsError.d.ts +13 -13
  16. package/src/errors/AccountExistsError.js +6 -6
  17. package/src/errors/ChainalysisError.cjs +5 -5
  18. package/src/errors/ChainalysisError.d.ts +5 -5
  19. package/src/errors/ChainalysisError.js +5 -5
  20. package/src/errors/CustomError.cjs +16 -16
  21. package/src/errors/CustomError.d.ts +11 -11
  22. package/src/errors/CustomError.js +16 -16
  23. package/src/errors/DynamicError.cjs +1 -1
  24. package/src/errors/DynamicError.d.ts +3 -3
  25. package/src/errors/DynamicError.js +1 -1
  26. package/src/errors/EmailAlreadyExistsError.cjs +4 -4
  27. package/src/errors/EmailAlreadyExistsError.d.ts +4 -4
  28. package/src/errors/EmailAlreadyExistsError.js +4 -4
  29. package/src/errors/EmailProviderError.cjs +4 -4
  30. package/src/errors/EmailProviderError.d.ts +4 -4
  31. package/src/errors/EmailProviderError.js +4 -4
  32. package/src/errors/EmailVerificationError.cjs +4 -4
  33. package/src/errors/EmailVerificationError.d.ts +4 -4
  34. package/src/errors/EmailVerificationError.js +4 -4
  35. package/src/errors/GateBlockedError.cjs +5 -5
  36. package/src/errors/GateBlockedError.d.ts +5 -5
  37. package/src/errors/GateBlockedError.js +5 -5
  38. package/src/errors/MissingEnvironmentIdError.cjs +4 -4
  39. package/src/errors/MissingEnvironmentIdError.d.ts +4 -4
  40. package/src/errors/MissingEnvironmentIdError.js +4 -4
  41. package/src/errors/NoAccessError.cjs +6 -6
  42. package/src/errors/NoAccessError.d.ts +9 -9
  43. package/src/errors/NoAccessError.js +6 -6
  44. package/src/errors/NotSupportedError.cjs +1 -1
  45. package/src/errors/NotSupportedError.d.ts +3 -3
  46. package/src/errors/NotSupportedError.js +1 -1
  47. package/src/errors/SocialAccountAlreadyExistsError.cjs +4 -4
  48. package/src/errors/SocialAccountAlreadyExistsError.d.ts +4 -4
  49. package/src/errors/SocialAccountAlreadyExistsError.js +4 -4
  50. package/src/errors/UserHasAccountWithEmailError.cjs +5 -5
  51. package/src/errors/UserHasAccountWithEmailError.d.ts +5 -5
  52. package/src/errors/UserHasAccountWithEmailError.js +5 -5
  53. package/src/errors/UsernameAlreadyExistsError.cjs +4 -4
  54. package/src/errors/UsernameAlreadyExistsError.d.ts +4 -4
  55. package/src/errors/UsernameAlreadyExistsError.js +4 -4
  56. package/src/errors/WalletNotDeployedError.cjs +4 -4
  57. package/src/errors/WalletNotDeployedError.d.ts +4 -4
  58. package/src/errors/WalletNotDeployedError.js +4 -4
  59. package/src/errors/WalletUsedError.cjs +4 -4
  60. package/src/errors/WalletUsedError.d.ts +4 -4
  61. package/src/errors/WalletUsedError.js +4 -4
  62. package/src/errors/index.d.ts +16 -16
  63. package/src/getOrMapViemChain.cjs +77 -0
  64. package/src/getOrMapViemChain.d.ts +11 -0
  65. package/src/getOrMapViemChain.js +51 -0
  66. package/src/{getPathFromObject.cjs → getProvidersFromWindow.cjs} +32 -28
  67. package/src/getProvidersFromWindow.d.ts +7 -0
  68. package/src/{getPathFromObject.js → getProvidersFromWindow.js} +32 -28
  69. package/src/index.cjs +17 -2
  70. package/src/index.d.ts +15 -10
  71. package/src/index.js +7 -2
  72. package/src/isBigInt/index.d.ts +1 -0
  73. package/src/isBigInt/isBigInt.cjs +7 -0
  74. package/src/isBigInt/isBigInt.d.ts +1 -0
  75. package/src/isBigInt/isBigInt.js +3 -0
  76. package/src/isFunction/index.d.ts +1 -1
  77. package/src/isFunction/isFunction.cjs +1 -1
  78. package/src/isFunction/isFunction.d.ts +1 -1
  79. package/src/isFunction/isFunction.js +1 -1
  80. package/src/isMobile.cjs +121 -110
  81. package/src/isMobile.d.ts +18 -16
  82. package/src/isMobile.js +120 -111
  83. package/src/last.cjs +14 -14
  84. package/src/last.d.ts +15 -15
  85. package/src/last.js +14 -14
  86. package/src/localStorageAsync.cjs +17 -17
  87. package/src/localStorageAsync.d.ts +3 -3
  88. package/src/localStorageAsync.js +17 -17
  89. package/src/logger/index.d.ts +1 -1
  90. package/src/logger/logger.d.ts +2 -2
  91. package/src/parseChainId.d.ts +1 -1
  92. package/src/parseEvmNetworks.cjs +6 -6
  93. package/src/parseEvmNetworks.d.ts +2 -2
  94. package/src/parseEvmNetworks.js +6 -6
  95. package/src/retryableFn.cjs +53 -0
  96. package/src/retryableFn.d.ts +14 -0
  97. package/src/retryableFn.js +48 -0
  98. package/src/sleep/index.d.ts +1 -0
  99. package/src/sleep/sleep.cjs +12 -0
  100. package/src/sleep/sleep.d.ts +11 -0
  101. package/src/sleep/sleep.js +8 -0
  102. package/src/getPathFromObject.d.ts +0 -8
package/src/isMobile.cjs CHANGED
@@ -2,118 +2,128 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- /**
6
- * Sourced from http://detectmobilebrowsers.com/
7
- */
8
- /* eslint-disable max-len, no-useless-escape */
9
- const userAgentRegex1 = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i;
10
- const userAgentRegex2 = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i;
11
- // This is a regex that covers both iphone, android and any other mobile device.
12
- const isMobile = (maxTouchPointsOverride) => {
13
- if (typeof window === 'undefined' || typeof navigator === 'undefined') {
14
- return false;
15
- }
16
- return (userAgentRegex1.test(navigator.userAgent) ||
17
- userAgentRegex2.test(navigator.userAgent.substring(0, 4)) ||
18
- isIPad(maxTouchPointsOverride) ||
19
- isIPhone());
20
- };
21
- const isIPhone = () => typeof window === 'undefined' || typeof navigator === 'undefined'
22
- ? false
23
- : /iPhone/.test(navigator.userAgent);
24
- const isIPhone8OrEarlier = () => typeof window === 'undefined' || typeof navigator === 'undefined'
25
- ? false
26
- : iPhoneLegacyRegex.some(({ regex }) => regex.test(navigator.userAgent));
27
- /**
28
- * @param [optional] maxTouchPointsOverride - this is used for testing since
29
- * it seems that JSDOM doesn't support maxTouchPoints, so it was impossible
30
- * to mock it
31
- */
32
- const isIPad = (maxTouchPointsOverride) => {
33
- if (typeof window === 'undefined' || typeof navigator === 'undefined') {
34
- return false;
35
- }
36
- const maxTouchPoints = maxTouchPointsOverride || navigator.maxTouchPoints;
37
- return (/iPad/.test(navigator.userAgent) ||
38
- (/Mac/.test(navigator.userAgent) && maxTouchPoints === 5));
39
- };
40
- const isIOS = (maxTouchPointsOverride) => {
41
- if (typeof window === 'undefined' || typeof navigator === 'undefined') {
42
- return false;
43
- }
44
- return isIPhone() || isIPad(maxTouchPointsOverride);
45
- };
46
- const isAndroid = () => isMobile() && !isIOS();
47
- const isLegacySafari = () => {
48
- // We need to check if window.CSS exists and if it has supports function.
49
- // We can use it only in browsers. This prevents customer tests from failing because of that.
50
- if (!window.CSS || typeof window.CSS.supports !== 'function') {
51
- return false;
52
- }
53
- // Older versions of Safari <15 are not supporting aspect-ratio css property.
54
- // We can use that to check if user is on older browser.
55
- // https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
56
- const cssValue = 'aspect-ratio: 1 / 1';
57
- return !CSS.supports(cssValue);
58
- };
59
- const isSamsungBrowser = () => {
60
- if (typeof window === 'undefined' || typeof navigator === 'undefined') {
61
- return false;
62
- }
63
- return navigator.userAgent.includes('SamsungBrowser');
64
- };
65
- // regex from: https://github.com/matomo-org/device-detector/blob/master/regexes/device/mobiles.yml
66
- const iPhoneLegacyRegex = [
67
- {
68
- model: 'iPhone 5',
69
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?5[C,_]12|5)$/,
70
- },
71
- {
72
- model: 'iPhone 5C',
73
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?5[C,_]34)$/,
74
- },
75
- {
76
- model: 'iPhone 5S',
77
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?6[C,_]12|5S)$/,
78
- },
79
- {
80
- model: 'iPhone 6 Plus',
81
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?7[C,_]1|1C2%257enohPi|6PLUS)$/,
82
- },
83
- {
84
- model: 'iPhone 6',
85
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?7[C,_]2|6)$/,
86
- },
87
- {
88
- model: 'iPhone 6s Plus',
89
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?8[C,_]2|6SPLUS)$/,
90
- },
91
- {
92
- model: 'iPhone 6s',
93
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?8[C,_]1|iPhone[ /]6s|6S)$/,
94
- },
95
- {
96
- model: 'iPhone SE',
97
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?8[C,_]4|SE)$/,
98
- },
99
- {
100
- model: 'iPhone 7',
101
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?9[C,_]13|iphone7|7)$/,
102
- },
103
- {
104
- model: 'iPhone 7 Plus',
105
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?9[C,_]24|7PLUS)$/,
106
- },
107
- {
108
- model: 'iPhone 8',
109
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?10[C,_]14|8)$/,
110
- },
111
- {
112
- model: 'iPhone 8 Plus',
113
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?10[C,_]25|8PLUS)$/,
114
- },
5
+ /**
6
+ * Sourced from http://detectmobilebrowsers.com/
7
+ */
8
+ /* eslint-disable max-len, no-useless-escape */
9
+ const userAgentRegex1 = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i;
10
+ const userAgentRegex2 = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i;
11
+ // This is a regex that covers both iphone, android and any other mobile device.
12
+ const isMobile = (maxTouchPointsOverride) => {
13
+ if (typeof window === 'undefined' || typeof navigator === 'undefined') {
14
+ return false;
15
+ }
16
+ return (userAgentRegex1.test(navigator.userAgent) ||
17
+ userAgentRegex2.test(navigator.userAgent.substring(0, 4)) ||
18
+ isIPad(maxTouchPointsOverride) ||
19
+ isIPhone());
20
+ };
21
+ const isIPhone = () => typeof window === 'undefined' || typeof navigator === 'undefined'
22
+ ? false
23
+ : /iPhone/.test(navigator.userAgent);
24
+ const isIPhone8OrEarlier = () => typeof window === 'undefined' || typeof navigator === 'undefined'
25
+ ? false
26
+ : iPhoneLegacyRegex.some(({ regex }) => regex.test(navigator.userAgent));
27
+ /**
28
+ * @param [optional] maxTouchPointsOverride - this is used for testing since
29
+ * it seems that JSDOM doesn't support maxTouchPoints, so it was impossible
30
+ * to mock it
31
+ */
32
+ const isIPad = (maxTouchPointsOverride) => {
33
+ if (typeof window === 'undefined' || typeof navigator === 'undefined') {
34
+ return false;
35
+ }
36
+ const maxTouchPoints = maxTouchPointsOverride || navigator.maxTouchPoints;
37
+ return (/iPad/.test(navigator.userAgent) ||
38
+ (/Mac/.test(navigator.userAgent) && maxTouchPoints === 5));
39
+ };
40
+ const isIOS = (maxTouchPointsOverride) => {
41
+ if (typeof window === 'undefined' || typeof navigator === 'undefined') {
42
+ return false;
43
+ }
44
+ return isIPhone() || isIPad(maxTouchPointsOverride);
45
+ };
46
+ const isAndroid = () => isMobile() && !isIOS();
47
+ const isLegacySafari = () => {
48
+ // We need to check if window.CSS exists and if it has supports function.
49
+ // We can use it only in browsers. This prevents customer tests from failing because of that.
50
+ if (!window.CSS || typeof window.CSS.supports !== 'function') {
51
+ return false;
52
+ }
53
+ // Older versions of Safari <15 are not supporting aspect-ratio css property.
54
+ // We can use that to check if user is on older browser.
55
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
56
+ const cssValue = 'aspect-ratio: 1 / 1';
57
+ return !CSS.supports(cssValue);
58
+ };
59
+ const isSamsungBrowser = () => {
60
+ if (typeof window === 'undefined' || typeof navigator === 'undefined') {
61
+ return false;
62
+ }
63
+ return navigator.userAgent.includes('SamsungBrowser');
64
+ };
65
+ const isWindows = () => window.navigator.userAgent.indexOf('Windows') !== -1;
66
+ // regex from: https://github.com/matomo-org/device-detector/blob/master/regexes/device/mobiles.yml
67
+ const iPhoneLegacyRegex = [
68
+ {
69
+ model: 'iPhone 5',
70
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?5[C,_]12|5)$/,
71
+ },
72
+ {
73
+ model: 'iPhone 5C',
74
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?5[C,_]34)$/,
75
+ },
76
+ {
77
+ model: 'iPhone 5S',
78
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?6[C,_]12|5S)$/,
79
+ },
80
+ {
81
+ model: 'iPhone 6 Plus',
82
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?7[C,_]1|1C2%257enohPi|6PLUS)$/,
83
+ },
84
+ {
85
+ model: 'iPhone 6',
86
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?7[C,_]2|6)$/,
87
+ },
88
+ {
89
+ model: 'iPhone 6s Plus',
90
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?8[C,_]2|6SPLUS)$/,
91
+ },
92
+ {
93
+ model: 'iPhone 6s',
94
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?8[C,_]1|iPhone[ /]6s|6S)$/,
95
+ },
96
+ {
97
+ model: 'iPhone SE',
98
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?8[C,_]4|SE)$/,
99
+ },
100
+ {
101
+ model: 'iPhone 7',
102
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?9[C,_]13|iphone7|7)$/,
103
+ },
104
+ {
105
+ model: 'iPhone 7 Plus',
106
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?9[C,_]24|7PLUS)$/,
107
+ },
108
+ {
109
+ model: 'iPhone 8',
110
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?10[C,_]14|8)$/,
111
+ },
112
+ {
113
+ model: 'iPhone 8 Plus',
114
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?10[C,_]25|8PLUS)$/,
115
+ },
115
116
  ];
117
+ const getAndroidVersion = () => {
118
+ const androidVersionMatch = navigator.userAgent.match(/Android (\d+(\.\d+)?)/);
119
+ if (!androidVersionMatch) {
120
+ return;
121
+ }
122
+ const androidVersion = parseFloat(androidVersionMatch[1]);
123
+ return androidVersion;
124
+ };
116
125
 
126
+ exports.getAndroidVersion = getAndroidVersion;
117
127
  exports.isAndroid = isAndroid;
118
128
  exports.isIOS = isIOS;
119
129
  exports.isIPad = isIPad;
@@ -122,3 +132,4 @@ exports.isIPhone8OrEarlier = isIPhone8OrEarlier;
122
132
  exports.isLegacySafari = isLegacySafari;
123
133
  exports.isMobile = isMobile;
124
134
  exports.isSamsungBrowser = isSamsungBrowser;
135
+ exports.isWindows = isWindows;
package/src/isMobile.d.ts CHANGED
@@ -1,16 +1,18 @@
1
- /**
2
- * Sourced from http://detectmobilebrowsers.com/
3
- */
4
- export declare const isMobile: (maxTouchPointsOverride?: number) => boolean;
5
- export declare const isIPhone: () => boolean;
6
- export declare const isIPhone8OrEarlier: () => boolean;
7
- /**
8
- * @param [optional] maxTouchPointsOverride - this is used for testing since
9
- * it seems that JSDOM doesn't support maxTouchPoints, so it was impossible
10
- * to mock it
11
- */
12
- export declare const isIPad: (maxTouchPointsOverride?: number) => boolean;
13
- export declare const isIOS: (maxTouchPointsOverride?: number) => boolean;
14
- export declare const isAndroid: () => boolean;
15
- export declare const isLegacySafari: () => boolean;
16
- export declare const isSamsungBrowser: () => boolean;
1
+ /**
2
+ * Sourced from http://detectmobilebrowsers.com/
3
+ */
4
+ export declare const isMobile: (maxTouchPointsOverride?: number) => boolean;
5
+ export declare const isIPhone: () => boolean;
6
+ export declare const isIPhone8OrEarlier: () => boolean;
7
+ /**
8
+ * @param [optional] maxTouchPointsOverride - this is used for testing since
9
+ * it seems that JSDOM doesn't support maxTouchPoints, so it was impossible
10
+ * to mock it
11
+ */
12
+ export declare const isIPad: (maxTouchPointsOverride?: number) => boolean;
13
+ export declare const isIOS: (maxTouchPointsOverride?: number) => boolean;
14
+ export declare const isAndroid: () => boolean;
15
+ export declare const isLegacySafari: () => boolean;
16
+ export declare const isSamsungBrowser: () => boolean;
17
+ export declare const isWindows: () => boolean;
18
+ export declare const getAndroidVersion: () => number | undefined;
package/src/isMobile.js CHANGED
@@ -1,113 +1,122 @@
1
- /**
2
- * Sourced from http://detectmobilebrowsers.com/
3
- */
4
- /* eslint-disable max-len, no-useless-escape */
5
- const userAgentRegex1 = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i;
6
- const userAgentRegex2 = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i;
7
- // This is a regex that covers both iphone, android and any other mobile device.
8
- const isMobile = (maxTouchPointsOverride) => {
9
- if (typeof window === 'undefined' || typeof navigator === 'undefined') {
10
- return false;
11
- }
12
- return (userAgentRegex1.test(navigator.userAgent) ||
13
- userAgentRegex2.test(navigator.userAgent.substring(0, 4)) ||
14
- isIPad(maxTouchPointsOverride) ||
15
- isIPhone());
16
- };
17
- const isIPhone = () => typeof window === 'undefined' || typeof navigator === 'undefined'
18
- ? false
19
- : /iPhone/.test(navigator.userAgent);
20
- const isIPhone8OrEarlier = () => typeof window === 'undefined' || typeof navigator === 'undefined'
21
- ? false
22
- : iPhoneLegacyRegex.some(({ regex }) => regex.test(navigator.userAgent));
23
- /**
24
- * @param [optional] maxTouchPointsOverride - this is used for testing since
25
- * it seems that JSDOM doesn't support maxTouchPoints, so it was impossible
26
- * to mock it
27
- */
28
- const isIPad = (maxTouchPointsOverride) => {
29
- if (typeof window === 'undefined' || typeof navigator === 'undefined') {
30
- return false;
31
- }
32
- const maxTouchPoints = maxTouchPointsOverride || navigator.maxTouchPoints;
33
- return (/iPad/.test(navigator.userAgent) ||
34
- (/Mac/.test(navigator.userAgent) && maxTouchPoints === 5));
35
- };
36
- const isIOS = (maxTouchPointsOverride) => {
37
- if (typeof window === 'undefined' || typeof navigator === 'undefined') {
38
- return false;
39
- }
40
- return isIPhone() || isIPad(maxTouchPointsOverride);
41
- };
42
- const isAndroid = () => isMobile() && !isIOS();
43
- const isLegacySafari = () => {
44
- // We need to check if window.CSS exists and if it has supports function.
45
- // We can use it only in browsers. This prevents customer tests from failing because of that.
46
- if (!window.CSS || typeof window.CSS.supports !== 'function') {
47
- return false;
48
- }
49
- // Older versions of Safari <15 are not supporting aspect-ratio css property.
50
- // We can use that to check if user is on older browser.
51
- // https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
52
- const cssValue = 'aspect-ratio: 1 / 1';
53
- return !CSS.supports(cssValue);
54
- };
55
- const isSamsungBrowser = () => {
56
- if (typeof window === 'undefined' || typeof navigator === 'undefined') {
57
- return false;
58
- }
59
- return navigator.userAgent.includes('SamsungBrowser');
60
- };
61
- // regex from: https://github.com/matomo-org/device-detector/blob/master/regexes/device/mobiles.yml
62
- const iPhoneLegacyRegex = [
63
- {
64
- model: 'iPhone 5',
65
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?5[C,_]12|5)$/,
66
- },
67
- {
68
- model: 'iPhone 5C',
69
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?5[C,_]34)$/,
70
- },
71
- {
72
- model: 'iPhone 5S',
73
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?6[C,_]12|5S)$/,
74
- },
75
- {
76
- model: 'iPhone 6 Plus',
77
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?7[C,_]1|1C2%257enohPi|6PLUS)$/,
78
- },
79
- {
80
- model: 'iPhone 6',
81
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?7[C,_]2|6)$/,
82
- },
83
- {
84
- model: 'iPhone 6s Plus',
85
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?8[C,_]2|6SPLUS)$/,
86
- },
87
- {
88
- model: 'iPhone 6s',
89
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?8[C,_]1|iPhone[ /]6s|6S)$/,
90
- },
91
- {
92
- model: 'iPhone SE',
93
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?8[C,_]4|SE)$/,
94
- },
95
- {
96
- model: 'iPhone 7',
97
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?9[C,_]13|iphone7|7)$/,
98
- },
99
- {
100
- model: 'iPhone 7 Plus',
101
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?9[C,_]24|7PLUS)$/,
102
- },
103
- {
104
- model: 'iPhone 8',
105
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?10[C,_]14|8)$/,
106
- },
107
- {
108
- model: 'iPhone 8 Plus',
109
- regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?10[C,_]25|8PLUS)$/,
110
- },
1
+ /**
2
+ * Sourced from http://detectmobilebrowsers.com/
3
+ */
4
+ /* eslint-disable max-len, no-useless-escape */
5
+ const userAgentRegex1 = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i;
6
+ const userAgentRegex2 = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i;
7
+ // This is a regex that covers both iphone, android and any other mobile device.
8
+ const isMobile = (maxTouchPointsOverride) => {
9
+ if (typeof window === 'undefined' || typeof navigator === 'undefined') {
10
+ return false;
11
+ }
12
+ return (userAgentRegex1.test(navigator.userAgent) ||
13
+ userAgentRegex2.test(navigator.userAgent.substring(0, 4)) ||
14
+ isIPad(maxTouchPointsOverride) ||
15
+ isIPhone());
16
+ };
17
+ const isIPhone = () => typeof window === 'undefined' || typeof navigator === 'undefined'
18
+ ? false
19
+ : /iPhone/.test(navigator.userAgent);
20
+ const isIPhone8OrEarlier = () => typeof window === 'undefined' || typeof navigator === 'undefined'
21
+ ? false
22
+ : iPhoneLegacyRegex.some(({ regex }) => regex.test(navigator.userAgent));
23
+ /**
24
+ * @param [optional] maxTouchPointsOverride - this is used for testing since
25
+ * it seems that JSDOM doesn't support maxTouchPoints, so it was impossible
26
+ * to mock it
27
+ */
28
+ const isIPad = (maxTouchPointsOverride) => {
29
+ if (typeof window === 'undefined' || typeof navigator === 'undefined') {
30
+ return false;
31
+ }
32
+ const maxTouchPoints = maxTouchPointsOverride || navigator.maxTouchPoints;
33
+ return (/iPad/.test(navigator.userAgent) ||
34
+ (/Mac/.test(navigator.userAgent) && maxTouchPoints === 5));
35
+ };
36
+ const isIOS = (maxTouchPointsOverride) => {
37
+ if (typeof window === 'undefined' || typeof navigator === 'undefined') {
38
+ return false;
39
+ }
40
+ return isIPhone() || isIPad(maxTouchPointsOverride);
41
+ };
42
+ const isAndroid = () => isMobile() && !isIOS();
43
+ const isLegacySafari = () => {
44
+ // We need to check if window.CSS exists and if it has supports function.
45
+ // We can use it only in browsers. This prevents customer tests from failing because of that.
46
+ if (!window.CSS || typeof window.CSS.supports !== 'function') {
47
+ return false;
48
+ }
49
+ // Older versions of Safari <15 are not supporting aspect-ratio css property.
50
+ // We can use that to check if user is on older browser.
51
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
52
+ const cssValue = 'aspect-ratio: 1 / 1';
53
+ return !CSS.supports(cssValue);
54
+ };
55
+ const isSamsungBrowser = () => {
56
+ if (typeof window === 'undefined' || typeof navigator === 'undefined') {
57
+ return false;
58
+ }
59
+ return navigator.userAgent.includes('SamsungBrowser');
60
+ };
61
+ const isWindows = () => window.navigator.userAgent.indexOf('Windows') !== -1;
62
+ // regex from: https://github.com/matomo-org/device-detector/blob/master/regexes/device/mobiles.yml
63
+ const iPhoneLegacyRegex = [
64
+ {
65
+ model: 'iPhone 5',
66
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?5[C,_]12|5)$/,
67
+ },
68
+ {
69
+ model: 'iPhone 5C',
70
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?5[C,_]34)$/,
71
+ },
72
+ {
73
+ model: 'iPhone 5S',
74
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?6[C,_]12|5S)$/,
75
+ },
76
+ {
77
+ model: 'iPhone 6 Plus',
78
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?7[C,_]1|1C2%257enohPi|6PLUS)$/,
79
+ },
80
+ {
81
+ model: 'iPhone 6',
82
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?7[C,_]2|6)$/,
83
+ },
84
+ {
85
+ model: 'iPhone 6s Plus',
86
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?8[C,_]2|6SPLUS)$/,
87
+ },
88
+ {
89
+ model: 'iPhone 6s',
90
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?8[C,_]1|iPhone[ /]6s|6S)$/,
91
+ },
92
+ {
93
+ model: 'iPhone SE',
94
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?8[C,_]4|SE)$/,
95
+ },
96
+ {
97
+ model: 'iPhone 7',
98
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?9[C,_]13|iphone7|7)$/,
99
+ },
100
+ {
101
+ model: 'iPhone 7 Plus',
102
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?9[C,_]24|7PLUS)$/,
103
+ },
104
+ {
105
+ model: 'iPhone 8',
106
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?10[C,_]14|8)$/,
107
+ },
108
+ {
109
+ model: 'iPhone 8 Plus',
110
+ regex: /(?:MDCR_|ICRU_|Apple-)?(?:iPh(?:one)?10[C,_]25|8PLUS)$/,
111
+ },
111
112
  ];
113
+ const getAndroidVersion = () => {
114
+ const androidVersionMatch = navigator.userAgent.match(/Android (\d+(\.\d+)?)/);
115
+ if (!androidVersionMatch) {
116
+ return;
117
+ }
118
+ const androidVersion = parseFloat(androidVersionMatch[1]);
119
+ return androidVersion;
120
+ };
112
121
 
113
- export { isAndroid, isIOS, isIPad, isIPhone, isIPhone8OrEarlier, isLegacySafari, isMobile, isSamsungBrowser };
122
+ export { getAndroidVersion, isAndroid, isIOS, isIPad, isIPhone, isIPhone8OrEarlier, isLegacySafari, isMobile, isSamsungBrowser, isWindows };
package/src/last.cjs CHANGED
@@ -2,20 +2,20 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- /**
6
- * Retrieves the last item from an array.
7
- *
8
- * @template T - The type of the items in the array.
9
- * @param {T[]} arr - The array from which to retrieve the last item.
10
- * @returns {T | undefined} The last item in the array, or undefined if the array is empty.
11
- *
12
- * @example
13
- * const numbers = [1, 2, 3, 4, 5];
14
- * console.log(last(numbers)); // Outputs: 5
15
- *
16
- * const emptyArray: number[] = [];
17
- * console.log(last(emptyArray)); // Outputs: undefined
18
- */
5
+ /**
6
+ * Retrieves the last item from an array.
7
+ *
8
+ * @template T - The type of the items in the array.
9
+ * @param {T[]} arr - The array from which to retrieve the last item.
10
+ * @returns {T | undefined} The last item in the array, or undefined if the array is empty.
11
+ *
12
+ * @example
13
+ * const numbers = [1, 2, 3, 4, 5];
14
+ * console.log(last(numbers)); // Outputs: 5
15
+ *
16
+ * const emptyArray: number[] = [];
17
+ * console.log(last(emptyArray)); // Outputs: undefined
18
+ */
19
19
  const last = (arr) => arr.length > 0 ? arr[arr.length - 1] : undefined;
20
20
 
21
21
  exports.last = last;
package/src/last.d.ts CHANGED
@@ -1,15 +1,15 @@
1
- /**
2
- * Retrieves the last item from an array.
3
- *
4
- * @template T - The type of the items in the array.
5
- * @param {T[]} arr - The array from which to retrieve the last item.
6
- * @returns {T | undefined} The last item in the array, or undefined if the array is empty.
7
- *
8
- * @example
9
- * const numbers = [1, 2, 3, 4, 5];
10
- * console.log(last(numbers)); // Outputs: 5
11
- *
12
- * const emptyArray: number[] = [];
13
- * console.log(last(emptyArray)); // Outputs: undefined
14
- */
15
- export declare const last: <T>(arr: T[]) => T | undefined;
1
+ /**
2
+ * Retrieves the last item from an array.
3
+ *
4
+ * @template T - The type of the items in the array.
5
+ * @param {T[]} arr - The array from which to retrieve the last item.
6
+ * @returns {T | undefined} The last item in the array, or undefined if the array is empty.
7
+ *
8
+ * @example
9
+ * const numbers = [1, 2, 3, 4, 5];
10
+ * console.log(last(numbers)); // Outputs: 5
11
+ *
12
+ * const emptyArray: number[] = [];
13
+ * console.log(last(emptyArray)); // Outputs: undefined
14
+ */
15
+ export declare const last: <T>(arr: T[]) => T | undefined;
package/src/last.js CHANGED
@@ -1,17 +1,17 @@
1
- /**
2
- * Retrieves the last item from an array.
3
- *
4
- * @template T - The type of the items in the array.
5
- * @param {T[]} arr - The array from which to retrieve the last item.
6
- * @returns {T | undefined} The last item in the array, or undefined if the array is empty.
7
- *
8
- * @example
9
- * const numbers = [1, 2, 3, 4, 5];
10
- * console.log(last(numbers)); // Outputs: 5
11
- *
12
- * const emptyArray: number[] = [];
13
- * console.log(last(emptyArray)); // Outputs: undefined
14
- */
1
+ /**
2
+ * Retrieves the last item from an array.
3
+ *
4
+ * @template T - The type of the items in the array.
5
+ * @param {T[]} arr - The array from which to retrieve the last item.
6
+ * @returns {T | undefined} The last item in the array, or undefined if the array is empty.
7
+ *
8
+ * @example
9
+ * const numbers = [1, 2, 3, 4, 5];
10
+ * console.log(last(numbers)); // Outputs: 5
11
+ *
12
+ * const emptyArray: number[] = [];
13
+ * console.log(last(emptyArray)); // Outputs: undefined
14
+ */
15
15
  const last = (arr) => arr.length > 0 ? arr[arr.length - 1] : undefined;
16
16
 
17
17
  export { last };