mazey 5.4.1 → 5.5.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.
package/README.md CHANGED
@@ -93,8 +93,10 @@ There are some examples maintained by hand below. For more information, please c
93
93
  - [formatDistanceToNow](#formatdistancetonow)
94
94
  - [generateCalendarVersion](#generatecalendarversion)
95
95
  - [formatDurationFromMs](#formatdurationfromms)
96
+ - [formatByteSize](#formatbytesize)
96
97
  - [deepCopy](#deepcopy)
97
98
  - [deepFreeze](#deepfreeze)
99
+ - [assignDefined](#assigndefined)
98
100
  - [debounce](#debounce)
99
101
  - [throttle](#throttle)
100
102
  - [convertCamelToKebab](#convertcameltokebab)
@@ -120,6 +122,7 @@ There are some examples maintained by hand below. For more information, please c
120
122
  - [genStyleString](#genstylestring)
121
123
  - [newLine](#newline)
122
124
  - [Calculate and Formula](#calculate-and-formula)
125
+ - [calculateCAGR](#calculatecagr)
123
126
  - [inRate](#inrate)
124
127
  - [longestComSubstring](#longestcomsubstring)
125
128
  - [longestComSubsequence](#longestcomsubsequence)
@@ -128,6 +131,7 @@ There are some examples maintained by hand below. For more information, please c
128
131
  - [setThemePreference](#setthemepreference)
129
132
  - [resolveLanguagePreference](#resolvelanguagepreference)
130
133
  - [setLanguagePreference](#setlanguagepreference)
134
+ - [detectVisitorType](#detectvisitortype)
131
135
  - [getBrowserInfo](#getbrowserinfo)
132
136
  - [isSafePWAEnv](#issafepwaenv)
133
137
  - [isStandalonePWA](#isstandalonepwa)
@@ -553,6 +557,26 @@ Output:
553
557
  1.5 days
554
558
  ```
555
559
 
560
+ #### formatByteSize
561
+
562
+ Format a non-negative byte count using 1024-based units and one fractional
563
+ digit by default. Decimal scaling, precision, and the invalid-input fallback
564
+ are configurable. The former `getFileSize` name is a deprecated alias.
565
+
566
+ ```javascript
567
+ formatByteSize(0);
568
+ formatByteSize(1536);
569
+ formatByteSize(1500000, { base: 1000, fractionDigits: 2 });
570
+ ```
571
+
572
+ Output:
573
+
574
+ ```text
575
+ 0 B
576
+ 1.5 KB
577
+ 1.50 MB
578
+ ```
579
+
556
580
  #### deepCopy
557
581
 
558
582
  Copy/Clone Object deeply.
@@ -598,6 +622,26 @@ true
598
622
  true
599
623
  ```
600
624
 
625
+ #### assignDefined
626
+
627
+ Shallowly mutate a target with defined properties from later sources. The
628
+ helper skips only `undefined`, so `null`, empty strings, `0`, and `false`
629
+ remain valid overrides.
630
+
631
+ ```javascript
632
+ const options = assignDefined(
633
+ { retries: 3, verbose: true },
634
+ { retries: undefined, verbose: false }
635
+ );
636
+ console.log(options);
637
+ ```
638
+
639
+ Output:
640
+
641
+ ```text
642
+ { retries: 3, verbose: false }
643
+ ```
644
+
601
645
  #### debounce
602
646
 
603
647
  Debounce
@@ -1088,6 +1132,54 @@ a<br /><br />bc
1088
1132
 
1089
1133
  ### Calculate and Formula
1090
1134
 
1135
+ #### calculateCAGR
1136
+
1137
+ Calculate an investment's Compound Annual Growth Rate (CAGR) from its start date, end date, and total return over the complete period.
1138
+
1139
+ ```text
1140
+ CAGR = (1 + totalReturnRate)^(365 / durationInDays) - 1
1141
+ ```
1142
+
1143
+ The dates may be supported structured date strings, millisecond timestamps, or `Date` instances. The calculation uses the exact elapsed milliseconds, including time-of-day components, and a fixed 365-day financial year.
1144
+
1145
+ Number input is a decimal ratio, so `0.202` represents `20.2%`. String input is a percentage value, so `"20.2%"` and `"20.2"` both represent `20.2%`; strict scientific notation such as `"2.02e1%"` is also accepted. The returned CAGR is an unrounded decimal ratio.
1146
+
1147
+ ```javascript
1148
+ import { calculateCAGR, floatToPercent } from "mazey";
1149
+
1150
+ const cagr = calculateCAGR(
1151
+ "2022-04-01",
1152
+ "2025-10-01",
1153
+ "20.2%"
1154
+ );
1155
+
1156
+ console.log({
1157
+ cagr,
1158
+ percentage: floatToPercent(cagr, 2),
1159
+ });
1160
+ ```
1161
+
1162
+ Possible output:
1163
+
1164
+ ```text
1165
+ {
1166
+ cagr: 0.053908...,
1167
+ percentage: "5.39%"
1168
+ }
1169
+ ```
1170
+
1171
+ The equivalent decimal-number call is:
1172
+
1173
+ ```javascript
1174
+ calculateCAGR(
1175
+ "2022-04-01",
1176
+ "2025-10-01",
1177
+ 0.202
1178
+ );
1179
+ ```
1180
+
1181
+ Date strings are validated using Mazey's strict date rules. Invalid dates, malformed or non-finite returns, and non-increasing date ranges throw errors. The parsed total return must be greater than `-1`, because `-1` represents a complete loss for which CAGR is undefined.
1182
+
1091
1183
  #### inRate
1092
1184
 
1093
1185
  Hit probability (1% ~ 100%).
@@ -1247,6 +1339,58 @@ const stored = setLanguagePreference(
1247
1339
 
1248
1340
  Output: `true`
1249
1341
 
1342
+ #### detectVisitorType
1343
+
1344
+ Conservatively classify a visitor as `"crawler"`, `"automation"`, or
1345
+ `"unknown"`. The function first checks a focused list of recognizable crawler,
1346
+ indexing, SEO, AI-fetcher, and link-preview user-agent tokens. It then checks
1347
+ explicit automation user-agent tokens and `navigator.webdriver === true`.
1348
+
1349
+ When no argument is provided, the function safely reads
1350
+ `navigator.userAgent`. An explicit user-agent string can be supplied for
1351
+ captured-user-agent analysis, deterministic tests, or server-side use. During
1352
+ SSR or in Node.js without `navigator`, the default result is `"unknown"`;
1353
+ explicit user-agent classification still works.
1354
+
1355
+ ```javascript
1356
+ const visitorType = detectVisitorType();
1357
+
1358
+ console.log(visitorType);
1359
+ ```
1360
+
1361
+ Possible output:
1362
+
1363
+ ```text
1364
+ unknown
1365
+ ```
1366
+
1367
+ Explicit crawler example:
1368
+
1369
+ ```javascript
1370
+ const visitorType = detectVisitorType(
1371
+ "Mozilla/5.0 (compatible; Googlebot/2.1)"
1372
+ );
1373
+
1374
+ console.log(visitorType);
1375
+ ```
1376
+
1377
+ Output:
1378
+
1379
+ ```text
1380
+ crawler
1381
+ ```
1382
+
1383
+ `"unknown"` means that no supported crawler or browser-automation signal was
1384
+ detected. User-agent values can be spoofed, and WebDriver signals can be hidden
1385
+ or changed, so false positives and false negatives are possible.
1386
+
1387
+ > `unknown` does not mean that the visitor has been verified as human. This
1388
+ > function uses browser-side heuristics and must not be used as a security
1389
+ > boundary or by itself for authentication, authorization, payments, rate
1390
+ > limiting, fraud prevention, or access control. Genuine crawler verification
1391
+ > generally requires server-side request information and provider-specific
1392
+ > validation.
1393
+
1250
1394
  #### getBrowserInfo
1251
1395
 
1252
1396
  Browser Information
package/README.zh-CN.md CHANGED
@@ -105,10 +105,12 @@ isNumber(z, { isInfinityAsNumber: true }); // 输出: true
105
105
  - [genStyleString](#genstylestring)
106
106
  - [newLine](#newline)
107
107
  - [计算与公式](#计算与公式)
108
+ - [calculateCAGR](#calculatecagr)
108
109
  - [inRate](#inrate)
109
110
  - [longestComSubstring](#longestcomsubstring)
110
111
  - [longestComSubsequence](#longestcomsubsequence)
111
112
  - [浏览器信息](#浏览器信息)
113
+ - [detectVisitorType](#detectvisitortype)
112
114
  - [getBrowserInfo](#getbrowserinfo)
113
115
  - [isSafePWAEnv](#issafepwaenv)
114
116
  - [isStandalonePWA](#isstandalonepwa)
@@ -982,6 +984,54 @@ a<br /><br />bc
982
984
 
983
985
  ### 计算与公式
984
986
 
987
+ #### calculateCAGR
988
+
989
+ 根据投资的开始日期、结束日期和整个周期的总回报率,计算复合年增长率(Compound Annual Growth Rate,CAGR)。
990
+
991
+ ```text
992
+ CAGR = (1 + totalReturnRate)^(365 / durationInDays) - 1
993
+ ```
994
+
995
+ 日期可以是支持的结构化日期字符串、毫秒时间戳或 `Date` 实例。计算使用精确的毫秒间隔,包括日期中的时分秒,并固定以 365 天作为一个财务年度。
996
+
997
+ 数值输入使用十进制比率,因此 `0.202` 表示 `20.2%`。字符串输入使用百分比数值,因此 `"20.2%"` 和 `"20.2"` 都表示 `20.2%`;也支持 `"2.02e1%"` 这类严格的科学记数法。返回的 CAGR 是未经舍入的十进制比率。
998
+
999
+ ```javascript
1000
+ import { calculateCAGR, floatToPercent } from "mazey";
1001
+
1002
+ const cagr = calculateCAGR(
1003
+ "2022-04-01",
1004
+ "2025-10-01",
1005
+ "20.2%"
1006
+ );
1007
+
1008
+ console.log({
1009
+ cagr,
1010
+ percentage: floatToPercent(cagr, 2),
1011
+ });
1012
+ ```
1013
+
1014
+ 可能的输出:
1015
+
1016
+ ```text
1017
+ {
1018
+ cagr: 0.053908...,
1019
+ percentage: "5.39%"
1020
+ }
1021
+ ```
1022
+
1023
+ 等效的十进制数值调用如下:
1024
+
1025
+ ```javascript
1026
+ calculateCAGR(
1027
+ "2022-04-01",
1028
+ "2025-10-01",
1029
+ 0.202
1030
+ );
1031
+ ```
1032
+
1033
+ 日期字符串遵循 Mazey 的严格日期校验规则。无效日期、格式错误或非有限的回报率,以及没有递增的日期范围都会抛出错误。解析后的总回报率必须大于 `-1`,因为 `-1` 表示本金完全损失,此时 CAGR 没有定义。
1034
+
985
1035
  #### inRate
986
1036
 
987
1037
  按照指定概率返回命中结果。有效概率范围为 1%~100%。
@@ -1051,6 +1101,44 @@ console.log(ret);
1051
1101
 
1052
1102
  ### 浏览器信息
1053
1103
 
1104
+ #### detectVisitorType
1105
+
1106
+ 此函数使用保守的启发式规则,将访问者分类为 `"crawler"`、`"automation"` 或 `"unknown"`。函数首先检查一组明确的 User-Agent 令牌。这些令牌来自爬虫、索引、SEO、AI 抓取和链接预览客户端。随后,函数检查显式的自动化 User-Agent 令牌,以及 `navigator.webdriver === true`。
1107
+
1108
+ 省略参数时,函数会安全地读取 `navigator.userAgent`。也可以传入明确的 User-Agent 字符串。此方式适合分析已捕获的 User-Agent、编写确定性测试或在服务端分类。SSR 或 Node.js 环境没有 `navigator` 时,默认返回 `"unknown"`。此时仍可传入明确的 User-Agent 进行分类。
1109
+
1110
+ ```javascript
1111
+ const visitorType = detectVisitorType();
1112
+
1113
+ console.log(visitorType);
1114
+ ```
1115
+
1116
+ 可能的输出:
1117
+
1118
+ ```text
1119
+ unknown
1120
+ ```
1121
+
1122
+ 下面的示例传入爬虫 User-Agent:
1123
+
1124
+ ```javascript
1125
+ const visitorType = detectVisitorType(
1126
+ "Mozilla/5.0 (compatible; Googlebot/2.1)"
1127
+ );
1128
+
1129
+ console.log(visitorType);
1130
+ ```
1131
+
1132
+ 输出:
1133
+
1134
+ ```text
1135
+ crawler
1136
+ ```
1137
+
1138
+ `"unknown"` 仅表示没有检测到受支持的爬虫或浏览器自动化信号。User-Agent 可以伪造,WebDriver 信号也可以隐藏或修改。因此,分类可能出现误判或漏判。
1139
+
1140
+ > `unknown` 不表示访问者已经通过真人验证。此函数只使用浏览器端启发式规则,不能作为安全边界。请勿单独使用此结果进行身份验证、授权、支付决策、速率限制、欺诈防范或访问控制。验证真实爬虫通常需要服务端请求信息,以及服务提供商规定的验证流程。
1141
+
1054
1142
  #### getBrowserInfo
1055
1143
 
1056
1144
  获取浏览器信息。