@fast-china/utils 1.0.38 → 2.0.2

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 (237) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/CONTRIBUTING.md +87 -0
  3. package/README.md +109 -50
  4. package/README.zh.md +109 -50
  5. package/SECURITY.md +46 -0
  6. package/dist/array/index.d.mts +87 -0
  7. package/dist/array/index.mjs +161 -0
  8. package/dist/array/index.mjs.map +1 -0
  9. package/dist/async/index.d.mts +146 -0
  10. package/dist/async/index.mjs +336 -0
  11. package/dist/async/index.mjs.map +1 -0
  12. package/dist/base64/index.d.mts +105 -0
  13. package/dist/base64/index.mjs +427 -0
  14. package/dist/base64/index.mjs.map +1 -0
  15. package/dist/color/index.d.mts +90 -0
  16. package/dist/color/index.mjs +178 -0
  17. package/dist/color/index.mjs.map +1 -0
  18. package/dist/crypto/index.d.mts +326 -0
  19. package/dist/crypto/index.mjs +843 -0
  20. package/dist/crypto/index.mjs.map +1 -0
  21. package/dist/date/index.d.mts +191 -0
  22. package/dist/date/index.mjs +383 -0
  23. package/dist/date/index.mjs.map +1 -0
  24. package/dist/dom/style.d.mts +30 -0
  25. package/dist/dom/style.mjs +74 -0
  26. package/dist/dom/style.mjs.map +1 -0
  27. package/dist/env/index.d.mts +63 -0
  28. package/dist/env/index.mjs +97 -0
  29. package/dist/env/index.mjs.map +1 -0
  30. package/dist/identity/index.d.mts +78 -0
  31. package/dist/identity/index.mjs +87 -0
  32. package/dist/identity/index.mjs.map +1 -0
  33. package/dist/index.d.mts +24 -0
  34. package/dist/index.global.min.js +3 -2
  35. package/dist/index.global.min.js.map +1 -1
  36. package/dist/index.mjs +23 -0
  37. package/dist/internal/text.mjs +36 -0
  38. package/dist/internal/text.mjs.map +1 -0
  39. package/dist/logger/index.d.mts +87 -0
  40. package/dist/logger/index.mjs +124 -0
  41. package/dist/logger/index.mjs.map +1 -0
  42. package/dist/number/index.d.mts +89 -0
  43. package/dist/number/index.mjs +215 -0
  44. package/dist/number/index.mjs.map +1 -0
  45. package/dist/object/index.d.mts +76 -0
  46. package/dist/object/index.mjs +134 -0
  47. package/dist/object/index.mjs.map +1 -0
  48. package/dist/storage/index.d.mts +107 -0
  49. package/dist/storage/index.mjs +327 -0
  50. package/dist/storage/index.mjs.map +1 -0
  51. package/dist/string/index.d.mts +130 -0
  52. package/dist/string/index.mjs +275 -0
  53. package/dist/string/index.mjs.map +1 -0
  54. package/dist/vue/emits.d.mts +24 -0
  55. package/dist/vue/emits.mjs +47 -0
  56. package/dist/vue/emits.mjs.map +1 -0
  57. package/dist/vue/expose.d.mts +12 -0
  58. package/dist/vue/expose.mjs +16 -0
  59. package/dist/vue/expose.mjs.map +1 -0
  60. package/dist/vue/func.d.mts +14 -0
  61. package/dist/vue/func.mjs +16 -0
  62. package/dist/vue/func.mjs.map +1 -0
  63. package/dist/vue/index.d.mts +9 -0
  64. package/dist/vue/install.d.mts +51 -0
  65. package/dist/vue/install.mjs +123 -0
  66. package/dist/vue/install.mjs.map +1 -0
  67. package/dist/vue/props.d.mts +23 -0
  68. package/dist/vue/props.mjs +41 -0
  69. package/dist/vue/props.mjs.map +1 -0
  70. package/dist/vue/render.d.mts +12 -0
  71. package/dist/vue/render.mjs +17 -0
  72. package/dist/vue/render.mjs.map +1 -0
  73. package/dist/vue/slots.d.mts +19 -0
  74. package/dist/vue/slots.mjs +13 -0
  75. package/dist/vue/slots.mjs.map +1 -0
  76. package/dist/vue/with.d.mts +12 -0
  77. package/dist/vue/with.mjs +15 -0
  78. package/dist/vue/with.mjs.map +1 -0
  79. package/docs/API.md +112 -0
  80. package/docs/API.zh-CN.md +112 -0
  81. package/docs/DEVELOPMENT_RELEASE.zh-CN.md +65 -0
  82. package/docs/RUNTIME_CONTRACT.md +37 -0
  83. package/package.json +63 -73
  84. package/dist/index.global.js +0 -14500
  85. package/dist/index.global.js.map +0 -1
  86. package/es/array/index.d.ts +0 -19
  87. package/es/array/index.mjs +0 -2
  88. package/es/array/index.mjs.map +0 -1
  89. package/es/base64/index.d.ts +0 -21
  90. package/es/base64/index.mjs +0 -2
  91. package/es/base64/index.mjs.map +0 -1
  92. package/es/click/index.d.ts +0 -33
  93. package/es/click/index.mjs +0 -2
  94. package/es/click/index.mjs.map +0 -1
  95. package/es/color/index.d.ts +0 -33
  96. package/es/color/index.mjs +0 -2
  97. package/es/color/index.mjs.map +0 -1
  98. package/es/console/index.d.ts +0 -31
  99. package/es/console/index.mjs +0 -2
  100. package/es/console/index.mjs.map +0 -1
  101. package/es/crypto/index.d.ts +0 -46
  102. package/es/crypto/index.mjs +0 -2
  103. package/es/crypto/index.mjs.map +0 -1
  104. package/es/date/index.d.ts +0 -44
  105. package/es/date/index.mjs +0 -2
  106. package/es/date/index.mjs.map +0 -1
  107. package/es/dom/index.d.ts +0 -1
  108. package/es/dom/index.mjs +0 -2
  109. package/es/dom/index.mjs.map +0 -1
  110. package/es/dom/style.d.ts +0 -12
  111. package/es/dom/style.mjs +0 -2
  112. package/es/dom/style.mjs.map +0 -1
  113. package/es/env/index.d.ts +0 -25
  114. package/es/env/index.mjs +0 -2
  115. package/es/env/index.mjs.map +0 -1
  116. package/es/error/index.d.ts +0 -3
  117. package/es/error/index.mjs +0 -2
  118. package/es/error/index.mjs.map +0 -1
  119. package/es/identity/index.d.ts +0 -14
  120. package/es/identity/index.mjs +0 -2
  121. package/es/identity/index.mjs.map +0 -1
  122. package/es/index.d.ts +0 -15
  123. package/es/index.es.d.ts +0 -2
  124. package/es/index.mjs +0 -2
  125. package/es/index.mjs.map +0 -1
  126. package/es/object/index.d.ts +0 -13
  127. package/es/object/index.mjs +0 -2
  128. package/es/object/index.mjs.map +0 -1
  129. package/es/storage/index.d.ts +0 -96
  130. package/es/storage/index.mjs +0 -2
  131. package/es/storage/index.mjs.map +0 -1
  132. package/es/string/index.d.ts +0 -114
  133. package/es/string/index.mjs +0 -2
  134. package/es/string/index.mjs.map +0 -1
  135. package/es/vue/emits.d.ts +0 -8
  136. package/es/vue/emits.mjs +0 -2
  137. package/es/vue/emits.mjs.map +0 -1
  138. package/es/vue/expose.d.ts +0 -4
  139. package/es/vue/expose.mjs +0 -2
  140. package/es/vue/expose.mjs.map +0 -1
  141. package/es/vue/func.d.ts +0 -6
  142. package/es/vue/func.mjs +0 -2
  143. package/es/vue/func.mjs.map +0 -1
  144. package/es/vue/index.d.ts +0 -8
  145. package/es/vue/index.mjs +0 -2
  146. package/es/vue/index.mjs.map +0 -1
  147. package/es/vue/install.d.ts +0 -5
  148. package/es/vue/install.mjs +0 -2
  149. package/es/vue/install.mjs.map +0 -1
  150. package/es/vue/props.d.ts +0 -9
  151. package/es/vue/props.mjs +0 -2
  152. package/es/vue/props.mjs.map +0 -1
  153. package/es/vue/slots.d.ts +0 -11
  154. package/es/vue/slots.mjs +0 -2
  155. package/es/vue/slots.mjs.map +0 -1
  156. package/es/vue/useRender.d.ts +0 -6
  157. package/es/vue/useRender.mjs +0 -2
  158. package/es/vue/useRender.mjs.map +0 -1
  159. package/es/vue/with.d.ts +0 -5
  160. package/es/vue/with.mjs +0 -2
  161. package/es/vue/with.mjs.map +0 -1
  162. package/lib/array/index.d.ts +0 -19
  163. package/lib/array/index.js +0 -2
  164. package/lib/array/index.js.map +0 -1
  165. package/lib/base64/index.d.ts +0 -21
  166. package/lib/base64/index.js +0 -2
  167. package/lib/base64/index.js.map +0 -1
  168. package/lib/click/index.d.ts +0 -33
  169. package/lib/click/index.js +0 -2
  170. package/lib/click/index.js.map +0 -1
  171. package/lib/color/index.d.ts +0 -33
  172. package/lib/color/index.js +0 -2
  173. package/lib/color/index.js.map +0 -1
  174. package/lib/console/index.d.ts +0 -31
  175. package/lib/console/index.js +0 -2
  176. package/lib/console/index.js.map +0 -1
  177. package/lib/crypto/index.d.ts +0 -46
  178. package/lib/crypto/index.js +0 -2
  179. package/lib/crypto/index.js.map +0 -1
  180. package/lib/date/index.d.ts +0 -44
  181. package/lib/date/index.js +0 -2
  182. package/lib/date/index.js.map +0 -1
  183. package/lib/dom/index.d.ts +0 -1
  184. package/lib/dom/index.js +0 -2
  185. package/lib/dom/index.js.map +0 -1
  186. package/lib/dom/style.d.ts +0 -12
  187. package/lib/dom/style.js +0 -2
  188. package/lib/dom/style.js.map +0 -1
  189. package/lib/env/index.d.ts +0 -25
  190. package/lib/env/index.js +0 -2
  191. package/lib/env/index.js.map +0 -1
  192. package/lib/error/index.d.ts +0 -3
  193. package/lib/error/index.js +0 -2
  194. package/lib/error/index.js.map +0 -1
  195. package/lib/identity/index.d.ts +0 -14
  196. package/lib/identity/index.js +0 -2
  197. package/lib/identity/index.js.map +0 -1
  198. package/lib/index.d.ts +0 -15
  199. package/lib/index.es.d.ts +0 -2
  200. package/lib/index.js +0 -2
  201. package/lib/index.js.map +0 -1
  202. package/lib/object/index.d.ts +0 -13
  203. package/lib/object/index.js +0 -2
  204. package/lib/object/index.js.map +0 -1
  205. package/lib/storage/index.d.ts +0 -96
  206. package/lib/storage/index.js +0 -2
  207. package/lib/storage/index.js.map +0 -1
  208. package/lib/string/index.d.ts +0 -114
  209. package/lib/string/index.js +0 -2
  210. package/lib/string/index.js.map +0 -1
  211. package/lib/vue/emits.d.ts +0 -8
  212. package/lib/vue/emits.js +0 -2
  213. package/lib/vue/emits.js.map +0 -1
  214. package/lib/vue/expose.d.ts +0 -4
  215. package/lib/vue/expose.js +0 -2
  216. package/lib/vue/expose.js.map +0 -1
  217. package/lib/vue/func.d.ts +0 -6
  218. package/lib/vue/func.js +0 -2
  219. package/lib/vue/func.js.map +0 -1
  220. package/lib/vue/index.d.ts +0 -8
  221. package/lib/vue/index.js +0 -2
  222. package/lib/vue/index.js.map +0 -1
  223. package/lib/vue/install.d.ts +0 -5
  224. package/lib/vue/install.js +0 -2
  225. package/lib/vue/install.js.map +0 -1
  226. package/lib/vue/props.d.ts +0 -9
  227. package/lib/vue/props.js +0 -2
  228. package/lib/vue/props.js.map +0 -1
  229. package/lib/vue/slots.d.ts +0 -11
  230. package/lib/vue/slots.js +0 -2
  231. package/lib/vue/slots.js.map +0 -1
  232. package/lib/vue/useRender.d.ts +0 -6
  233. package/lib/vue/useRender.js +0 -2
  234. package/lib/vue/useRender.js.map +0 -1
  235. package/lib/vue/with.d.ts +0 -5
  236. package/lib/vue/with.js +0 -2
  237. package/lib/vue/with.js.map +0 -1
@@ -0,0 +1,112 @@
1
+ # Fast.Utils API
2
+
3
+ Fast.Utils 是面向浏览器的 ES2022 工具包;包管理器使用 ESM 入口,CDN 使用单独压缩的 IIFE 入口。应用环境包括现代浏览器、WebView、Vue 3 和 uni-app。
4
+
5
+ ## 导入
6
+
7
+ 包只提供一个公开根入口,包含普通工具和 Vue Helper 在内的全部 API 均使用具名导出。
8
+
9
+ ```ts
10
+ import { chunk, configureStorage, installationIdentity, Local } from "@fast-china/utils";
11
+ ```
12
+
13
+ 内部 Helper 不提供公共子路径。库不再导出工具聚合对象,调用方应直接导入具名函数,以便 Tree Shaking。
14
+
15
+ ## Storage
16
+
17
+ `Local` 和 `Session` 会以旧版兼容的 `fast__` 前缀、JSON Codec 与 `Date.now` 延迟初始化。除非需要覆盖默认值,否则无需调用 `configureStorage`。
18
+
19
+ ```ts
20
+ import { Local, Session } from "@fast-china/utils";
21
+
22
+ Local.set("profile", { name: "Ada" }, { ttlMs: 3_600_000 });
23
+ Session.set("draft", { step: 2 });
24
+ ```
25
+
26
+ `Local` 和 `Session` 提供 `get`、`set`、`has`、`remove`、`removeByPrefix`、`keys`、`pruneExpired` 和仅清理当前命名空间的 `clear`。键缺失或过期时返回 `undefined`。TTL 非法、Prefix 为空、存储包络损坏、平台 Storage 不可用或重复配置发生冲突时抛出错误;浏览器配额与隐私策略错误直接向上传播。自定义选项必须在首次 Storage 操作前配置。
27
+
28
+ uni-app 中,首次 Storage 操作或显式调用 `configureStorage` 会自动检测全局 `uni` 并使用其同步 Storage API。uni-app 没有独立 Session 后端,因此该模式调用 `Session` 会明确抛错。
29
+
30
+ ```ts
31
+ import { Local } from "@fast-china/utils";
32
+
33
+ Local.set("token", "value");
34
+ ```
35
+
36
+ `configureStorage({ prefix: "admin:", crypto: true })` 恢复了旧版全局前缀与 Base64 混淆选项。`crypto: true` 和 `base64StorageCodec` 都只是可逆编码,不是加密,不能保护敏感数据。可以使用自定义 `codec` 替代 `crypto`。
37
+
38
+ `encodeSecureBase64` 与 `decodeSecureBase64` 保留旧字典兼容载荷,并使用 Web Crypto 生成安全随机前缀。给定相同的默认 6 字符前缀时,有效旧载荷保持逐字符兼容;旧字典在 Base64 长度 101–124 时会引用越界,当前实现使用单字符回退,旧删除字典流程仍可解码。旧自定义长度参数始终生成 6 个随机字符,当前 API 已按 `prefixLength` 正确生成。自定义 `prefixLength` 必须在编码和解码时保持一致;传入 `0` 会同时关闭随机前缀与字典插入。该格式仍是可逆编码,不等同于加密。
39
+
40
+ ## Identity
41
+
42
+ `installationIdentity` 是全局安装标识门面。可在程序入口、首次使用前调用 `configureInstallationIdentity` 覆盖默认缓存键 `identity:installation-id`。`getOrCreateInstallationId(installationId?)` 会通过 `Local` 读取、生成或替换 UUID v4;未显式配置 Storage 时使用其默认值。UUID 生成依赖 Web Crypto,不会回退到 `Math.random()`。
43
+
44
+ ```ts
45
+ import { configureInstallationIdentity, configureStorage, getOrCreateInstallationId, installationIdentity } from "@fast-china/utils";
46
+
47
+ configureStorage({ prefix: "app:" });
48
+ configureInstallationIdentity({ cacheKey: "account:installation-id" });
49
+ getOrCreateInstallationId();
50
+ installationIdentity.read();
51
+ installationIdentity.clear();
52
+ ```
53
+
54
+ 这个 ID 只标识当前存储空间中的安装实例,不是硬件标识、认证凭证、秘密或反欺诈信号。
55
+
56
+ ## Logger
57
+
58
+ Logger 作用域属于每条日志,不保存在可变 Logger 或 Child 实例中:
59
+
60
+ ```ts
61
+ import { logger } from "@fast-china/utils";
62
+
63
+ logger.info("storage", "profile loaded", { userId: 1 });
64
+ logger.error("network", "request failed", error);
65
+ ```
66
+
67
+ `createLogger` 只配置最低级别、品牌前缀、Sink 和可选的 uni-app App-Plus 拆分输出。作用域必须是无外围空白的非空字符串。
68
+
69
+ ## Crypto
70
+
71
+ TypeScript Crypto 公共 API 与 .NET `CryptoUtil` 的公开方法及算法名称大小写保持一致:
72
+
73
+ | 能力 | 两端统一的方法名 |
74
+ | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
75
+ | 安全随机与字节比较 | `GenerateRandomBytes`、`FixedTimeEquals` |
76
+ | MD5、SHA-1 与 SHA-2 摘要 | `MD5Encrypt`、`SHA1Encrypt`、`SHA256Encrypt`、`SHA256Bytes`、`SHA384Encrypt`、`SHA384Bytes`、`SHA512Encrypt`、`SHA512Bytes` |
77
+ | HMAC | `HMACSHA256Encrypt`、`HMACSHA384Encrypt`、`HMACSHA512Encrypt` |
78
+ | 密码派生与密码哈希 | `PBKDF2SHA256`、`HashPasswordPBKDF2SHA256`、`VerifyPasswordPBKDF2SHA256` |
79
+ | HKDF | `HKDFSHA256` |
80
+ | AES | `AESEncrypt`、`AESDecrypt`、`AESEncryptAuthenticated`、`AESDecryptAuthenticated`、`AESEncryptWithPassword`、`AESDecryptWithPassword` |
81
+ | RSA | `GenerateRSAKeyPair`、`RSAEncryptOAEP`、`RSADecryptOAEP`、`RSASignPSS`、`RSAVerifyPSS` |
82
+ | 椭圆曲线 | `GenerateECDSAKeyPair`、`ECDSASign`、`ECDSAVerify`、`GenerateECDHKeyPair`、`DeriveECDHSecret`、`DeriveECDHKeySHA256` |
83
+
84
+ `AESEncryptAuthenticated` 的 Base64 v1 载荷、`AESEncryptWithPassword` 的 `FAST-AES-256-GCM-V2` 载荷、PBKDF2 密码哈希以及 PKCS#8/SPKI PEM 密钥均可与 .NET 双向使用。MD5 与 HMAC 输出小写十六进制;SHA-1/256/384/512 输出大写十六进制,与 .NET 保持一致。
85
+
86
+ 密码存储使用 `HashPasswordPBKDF2SHA256` 和 `VerifyPasswordPBKDF2SHA256`;该哈希不可解密。需要同时保证机密性和完整性的文本使用 AES-GCM 入口。HMAC 用于共享密钥认证,SHA-2 用于摘要,HKDF/PBKDF2 用于密钥派生。MD5、SHA-1、AES-CBC 和 AES-ECB 不提供现代密码存储或认证加密保证。
87
+
88
+ ## 模块
89
+
90
+ - `array`:分块、压缩、去重、分组、分区、差集、交集和一致性判断。
91
+ - `async`:支持取消的 Sleep、超时、重试、受限并发映射、防抖和节流。
92
+ - `base64`:严格 UTF-8 Base64/Base64URL 字节与文本函数,以及 Latin-1 和 SecureBase64 兼容函数。
93
+ - `color`:颜色解析、格式化、混合、明暗、亮度和对比度。
94
+ - `crypto`:安全随机、摘要、HMAC、PBKDF2、HKDF、AES、RSA-OAEP/PSS、ECDSA 和 ECDH。
95
+ - `date`:日期校验、加减、日范围、相对时间,以及七个历史日期功能的具名函数。
96
+ - `dom`:CSS 单位和 Style 序列化。
97
+ - `env`:能力与 User-Agent 检测;检测函数不扩大运行时支持范围。
98
+ - `logger`:隔离的可配置 Logger 和默认 `logger`。
99
+ - `number`:范围、舍入、聚合、插值、字节格式化和安全随机整数。
100
+ - `object`:防原型污染的选择、比较、映射和 Query 序列化;Style 序列化由 `dom` 模块提供。
101
+ - `string`:Query 解析、大小写、字素截断、UUID、安全随机文本、转义和空白规范化。
102
+ - `vue`:Vue 3 的 Composition API、类型、Render 和 `app.use()` 注册 Helper。
103
+
104
+ ## 安全与限制
105
+
106
+ AES-GCM 提供机密性和完整性;AES-CBC/ECB 不提供认证。MD5、SHA-1 和历史 Base64 字典不能用于密码存储、签名或受保护数据。Crypto API 按算法限制参数和载荷大小,并在需要时强制要求 Web Crypto。
107
+
108
+ Query 与 Object API 拒绝原型污染键,URL 解码有最大深度,Storage 清理只作用于配置的命名空间。浏览器全局对象只在调用 API 时解析,模块导入阶段不会访问。
109
+
110
+ ## 错误与兼容性
111
+
112
+ 除明确说明返回空值的函数外,编程错误、非法输入、平台能力缺失和受保护数据损坏均抛出原生错误。
@@ -0,0 +1,65 @@
1
+ # Fast.Utils 开发与发布
2
+
3
+ ## 基线
4
+
5
+ - Node.js:`^22.18.0 || ^24.18.0`。
6
+ - pnpm:`^11.0.0`,不固定补丁版本。
7
+ - TypeScript 6、tsdown、ESLint 10 Flat Config、Prettier 3。
8
+ - 发布格式:包管理器使用 ESM、`.mjs` 与 `.d.mts`,CDN 使用压缩 IIFE;两类 JavaScript 产物均提供 Source Map。
9
+ - 根目录是唯一 npm 发布单元,根 `dist/` 是唯一产物目录。
10
+
11
+ 应用环境包括现代浏览器、WebView、Vue 3 和 uni-app。
12
+
13
+ ## 安装与命令
14
+
15
+ ```bash
16
+ corepack enable
17
+ pnpm install --frozen-lockfile
18
+ ```
19
+
20
+ | 命令 | 用途 |
21
+ | ------------------- | ---------------------------------------------------------------------- |
22
+ | `pnpm dev` | 使用 tsdown 监听源码并增量构建 |
23
+ | `pnpm build` | 使用 tsdown 构建 ESM 模块与压缩 IIFE |
24
+ | `pnpm typecheck` | 检查源码与构建配置类型 |
25
+ | `pnpm lint` | 运行零警告 ESLint |
26
+ | `pnpm format:check` | 检查 Prettier |
27
+ | `pnpm test:types` | 验证公开消费者类型 |
28
+ | `pnpm test:runtime` | 运行单元、平台与 Vue Runtime 测试 |
29
+ | `pnpm test:package` | 验证 Tarball、公开入口、声明、Source Map、Tree Shaking、体积与 Publint |
30
+ | `pnpm check` | 运行统一质量门禁 |
31
+
32
+ ## 修改公共模块
33
+
34
+ 新增公共模块时必须同步:
35
+
36
+ 1. 在 `src/<module>/index.ts` 定义具名 API 和 TSDoc。
37
+ 2. 在 `src/index.ts` 统一重新导出公共 API。
38
+ 3. 不为模块增加 `package.json#exports` 子路径或独立构建入口。
39
+ 4. 增加源码类型、消费者类型、单元和真实包测试。
40
+ 5. 更新双语 README、API 和 Changelog。
41
+
42
+ 禁止在导入阶段访问浏览器或 uni-app 全局对象。平台能力应在调用阶段解析;`configureStorage` 在调用时自动检测全局 `uni`。
43
+
44
+ ## 依赖与锁文件
45
+
46
+ - Runtime Dependency 必须证明无法由平台能力或小型实现替代。
47
+ - Vue 3.3+ 是必须安装的 Peer Dependency;ESM 与 IIFE 均保持外部引用,不打包进发布产物。
48
+ - 依赖升级后使用当前 pnpm 11 更新 Lockfile,并通过 Frozen Lockfile 安装验证。
49
+ - 不混用 npm、Yarn 或不同 pnpm 主版本改写 Lockfile。
50
+
51
+ ## CI
52
+
53
+ CI 在 Node 22 与 24 上运行,使用 Frozen Lockfile,并执行 `pnpm check` 与 Pack Dry Run。不得通过关闭类型、Lint、测试或包验证来修复门禁。
54
+
55
+ ## 发布
56
+
57
+ 仓库只采用人工发布流程,不声明或配置 OIDC Trusted Publishing:
58
+
59
+ 1. 更新 SemVer 与 `CHANGELOG.md` 日期。
60
+ 2. 执行 `pnpm install --frozen-lockfile`。
61
+ 3. 执行 `pnpm check`。
62
+ 4. 人工检查 `pnpm --config.ignore-scripts=true pack --dry-run` 清单。
63
+ 5. 由维护者在可信环境执行 npm Publish,并创建对应 `v<version>` Tag。
64
+
65
+ 未经明确授权,不执行 Publish、Push、Tag 或 Release。npm 已发布版本不可覆盖;发布后缺陷必须通过新 Patch 或 Pre-release 修复。
@@ -0,0 +1,37 @@
1
+ # Fast.Utils runtime contract / 运行时契约
2
+
3
+ ## Runtime and package contract
4
+
5
+ - Runtime platforms: ES2022 modern browsers, WebViews, Vue 3 applications, and uni-app.
6
+ - Package format: one public named-export ESM entry for package managers and one separately minified IIFE entry for CDN use; CommonJS and UMD are not shipped.
7
+ - Framework boundary: Vue remains external to the package-manager build and is a required peer in `^3.3.0`.
8
+ - uni-app boundary: the first Storage operation, or an earlier `configureStorage({ prefix })` call, detects global `uni` and uses its synchronous Storage API.
9
+ - Browser storage: applications import `Local` and `Session` directly; `configureStorage()` is needed only to override defaults before the first operation.
10
+ - Stateful browser defaults: Storage and Identity configuration are page-global by design. Conflicting reconfiguration throws.
11
+ - Security: secure random APIs require Web Crypto and never fall back to `Math.random()`.
12
+ - Publishing: the repository root is the only package, `dist/` is the only build output, and `package.json#exports` is the complete public path whitelist.
13
+
14
+ Importing a module does not itself read `window`, browser Storage, or `uni`, so unsupported platform capabilities fail only when the corresponding API is called.
15
+
16
+ ## Public API policy
17
+
18
+ - Stateless Array, Date, String, Number, Object, Base64, Color, DOM, Env, Async, and Crypto capabilities use named exports.
19
+ - The public API uses named functions instead of mutable aggregate utility objects.
20
+ - Stateful browser capabilities use cohesive package-owned objects: `Local`, `Session`, `installationIdentity`, and logger instances. Logger scope is supplied to each severity method rather than stored in child instances.
21
+ - Internal adapters and client factories are implementation details and are not public export paths.
22
+ - Removing a named function, changing Storage/ciphertext formats, raising the browser syntax target, or changing the Vue peer range requires an explicit major-version Breaking Change.
23
+
24
+ ## 运行时与包契约
25
+
26
+ - 运行平台:ES2022 现代浏览器、WebView、Vue 3 应用和 uni-app。
27
+ - 包格式:包管理器使用单一公开具名导出 ESM 入口,CDN 使用单独压缩的 IIFE;不发布 CommonJS 或 UMD。
28
+ - Vue 边界:Vue 不会打进包管理器使用的构建产物,是 `^3.3.0` 的必需 Peer。
29
+ - uni-app:首次 Storage 操作或更早的 `configureStorage({ prefix })` 调用会检测全局 `uni`,并使用其同步 Storage API。
30
+ - Storage:直接从包导入 `Local` 和 `Session` 即可;只有覆盖默认值时才需在首次操作前调用 `configureStorage()`。
31
+ - 状态:Storage 与 Identity 配置按浏览器页面全局共享;冲突配置明确抛错。
32
+ - 安全随机:要求 Web Crypto,禁止回退 `Math.random()`。
33
+ - 发布:根目录是唯一 npm 包,`dist/` 是唯一构建输出,`exports` 是完整公共路径白名单。
34
+
35
+ 模块导入本身不读取 `window`、浏览器 Storage 或 `uni`,不具备对应平台能力时只在调用相关 API 时明确失败。
36
+
37
+ 无状态能力统一使用具名导出。有状态浏览器能力使用 `Local`、`Session`、`installationIdentity` 和 Logger 实例;Logger 作用域随每次级别方法调用传入,不创建 Child Logger。
package/package.json CHANGED
@@ -1,104 +1,94 @@
1
1
  {
2
2
  "name": "@fast-china/utils",
3
- "version": "1.0.38",
4
- "description": "Fast 工具库.",
3
+ "version": "2.0.2",
4
+ "description": "Typed utilities for modern browsers, WebViews, Vue 3, and uni-app applications.",
5
5
  "type": "module",
6
6
  "keywords": [
7
- "fast-china",
8
7
  "fast",
8
+ "fast-china",
9
9
  "typescript",
10
10
  "utils"
11
11
  ],
12
12
  "license": "Apache-2.0",
13
13
  "homepage": "https://fastdotnet.com",
14
14
  "bugs": {
15
- "url": "https://gitee.com/FastDotnet/Fast.Utils/issues"
15
+ "url": "https://gitee.com/FastDotnet/fast.utils/issues"
16
16
  },
17
17
  "repository": {
18
18
  "type": "git",
19
- "url": "https://gitee.com/FastDotnet/Fast.Utils"
19
+ "url": "https://gitee.com/FastDotnet/fast.utils"
20
20
  },
21
21
  "author": "小方",
22
22
  "files": [
23
- "./Fast.png",
24
- "./LICENSE",
25
- "./README.md",
26
- "./README.zh.md",
27
- "./dist",
28
- "./es",
29
- "./lib"
23
+ "CHANGELOG.md",
24
+ "CONTRIBUTING.md",
25
+ "Fast.png",
26
+ "LICENSE",
27
+ "README.md",
28
+ "README.zh.md",
29
+ "SECURITY.md",
30
+ "dist",
31
+ "docs"
30
32
  ],
31
- "main": "lib/index.js",
32
- "module": "es/index.mjs",
33
- "types": "es/index.d.ts",
33
+ "main": "./dist/index.mjs",
34
+ "module": "./dist/index.mjs",
35
+ "types": "./dist/index.d.mts",
34
36
  "exports": {
35
37
  ".": {
36
- "types": "./es/index.d.ts",
37
- "require": "./lib/index.js",
38
- "import": "./es/index.mjs"
39
- },
40
- "./es": {
41
- "types": "./es/index.d.ts",
42
- "import": "./es/index.mjs"
43
- },
44
- "./lib": {
45
- "types": "./lib/index.d.ts",
46
- "require": "./lib/index.js"
47
- },
48
- "./es/*.mjs": {
49
- "types": "./es/*.d.ts",
50
- "import": "./es/*.mjs"
51
- },
52
- "./es/*": {
53
- "types": [
54
- "./es/*.d.ts",
55
- "./es/*/index.d.ts"
56
- ],
57
- "import": "./es/*.mjs"
58
- },
59
- "./lib/*.js": {
60
- "types": "./lib/*.d.ts",
61
- "require": "./lib/*.js"
62
- },
63
- "./lib/*": {
64
- "types": [
65
- "./lib/*.d.ts",
66
- "./lib/*/index.d.ts"
67
- ],
68
- "require": "./lib/*.js"
69
- },
70
- "./*": "./*"
38
+ "types": "./dist/index.d.mts",
39
+ "import": "./dist/index.mjs",
40
+ "default": "./dist/index.mjs"
41
+ }
71
42
  },
72
- "unpkg": "dist/index.global.min.js",
73
- "jsdelivr": "dist/index.global.min.js",
43
+ "sideEffects": false,
44
+ "unpkg": "./dist/index.global.min.js",
45
+ "jsdelivr": "./dist/index.global.min.js",
74
46
  "publishConfig": {
75
47
  "access": "public"
76
48
  },
49
+ "scripts": {
50
+ "dev": "tsdown --watch",
51
+ "build": "tsdown",
52
+ "typecheck": "tsc --noEmit",
53
+ "lint": "eslint . --max-warnings 0",
54
+ "lint:fix": "eslint . --fix",
55
+ "format": "prettier --write .",
56
+ "format:check": "prettier --check .",
57
+ "test": "pnpm run build && pnpm run test:types && pnpm run test:runtime && pnpm run test:package",
58
+ "test:types": "tsc --noEmit --project tests/tsconfig.json",
59
+ "test:runtime": "node --import tsx --test tests/async.test.ts tests/core.test.ts tests/storage-crypto.test.ts tests/storage-default.test.ts tests/storage-uni.test.ts tests/vue.test.ts",
60
+ "test:package": "node --test tests/package.test.mjs && publint --strict --pack npm",
61
+ "check": "pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run format:check",
62
+ "prepack": "pnpm run check"
63
+ },
77
64
  "peerDependencies": {
78
- "vue": "^2 || ^3"
65
+ "vue": "^3.3.0"
79
66
  },
80
67
  "dependencies": {
81
- "@types/crypto-js": "^4.2",
82
- "@types/lodash": "^4.17",
83
- "@types/lodash-es": "^4.17",
84
- "crypto-js": "^4.2",
85
- "lodash": "^4.17",
86
- "lodash-es": "^4.17",
87
- "lodash-unified": "^1"
68
+ "crypto-js": "^4.2.0"
88
69
  },
89
70
  "devDependencies": {
90
- "@dcloudio/types": "^3",
91
- "@fast-china/eslint-config": "^1",
92
- "@rollup/plugin-terser": "^0.4",
93
- "@types/node": "^24",
94
- "@vue/tsconfig": "^0.8",
95
- "eslint": "^9",
96
- "prettier": "^3",
97
- "terser": "^5",
98
- "typescript": "^5",
99
- "vite": "^7",
100
- "vite-plugin-dts": "^4",
101
- "vue": "^2 || ^3",
102
- "vue-tsc": "^3"
71
+ "@eslint/js": "^10.0.1",
72
+ "@eslint/markdown": "^8.0.3",
73
+ "@types/crypto-js": "^4.2.2",
74
+ "@types/node": "^24.13.3",
75
+ "eslint": "^10.8.0",
76
+ "eslint-config-flat-gitignore": "^2.3.0",
77
+ "eslint-config-prettier": "^10.1.8",
78
+ "eslint-plugin-import-x": "^4.17.1",
79
+ "eslint-plugin-jsonc": "^3.3.0",
80
+ "eslint-plugin-regexp": "^3.1.1",
81
+ "globals": "^17.8.0",
82
+ "prettier": "^3.9.6",
83
+ "publint": "^0.3.22",
84
+ "tsdown": "^0.22.14",
85
+ "tsx": "^4.23.1",
86
+ "typescript": "^6.0.3",
87
+ "typescript-eslint": "^8.65.0",
88
+ "vue": "^3.5.40"
89
+ },
90
+ "engines": {
91
+ "node": "^22.18.0 || ^24.18.0",
92
+ "pnpm": "^11.0.0"
103
93
  }
104
94
  }