@anjianshi/utils 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/README.md +10 -0
  2. package/eslint.config.cjs +33 -0
  3. package/package.json +26 -15
  4. package/publish-prepare.cjs +16 -0
  5. package/src/env-browser/device.ts +62 -0
  6. package/src/env-browser/global.ts +21 -0
  7. package/src/env-browser/load-script.ts +13 -0
  8. package/src/env-browser/logging.ts +58 -0
  9. package/src/env-browser/manage-vconsole.ts +54 -0
  10. package/src/env-node/crypto-random.ts +30 -0
  11. package/src/env-node/fs.ts +50 -0
  12. package/src/env-node/index.ts +6 -0
  13. package/src/env-node/logging/handlers.ts +190 -0
  14. package/src/env-node/logging/index.ts +16 -0
  15. package/src/env-node/safe-request.ts +66 -0
  16. package/src/env-react/emotion.tsx +42 -0
  17. package/src/env-service/controllers.ts +93 -0
  18. package/src/env-service/env-reader.ts +141 -0
  19. package/src/env-service/index.ts +6 -0
  20. package/src/env-service/prisma/adapt-logging.ts +39 -0
  21. package/src/env-service/prisma/extensions/exist.ts +21 -0
  22. package/src/env-service/prisma/extensions/find-and-count.ts +24 -0
  23. package/src/env-service/prisma/extensions/soft-delete.ts +162 -0
  24. package/src/env-service/prisma/extensions/with-transaction.ts +65 -0
  25. package/src/env-service/prisma/index.ts +6 -0
  26. package/src/env-service/prisma/transaction-contexted.ts +80 -0
  27. package/src/env-service/redis-cache.ts +142 -0
  28. package/src/env-service/tasks.ts +45 -0
  29. package/src/index.ts +3 -0
  30. package/src/init-dayjs.ts +8 -0
  31. package/src/lang/async.ts +47 -0
  32. package/src/lang/color.ts +119 -0
  33. package/src/lang/index.ts +7 -0
  34. package/src/lang/may-success.ts +57 -0
  35. package/src/lang/object.ts +39 -0
  36. package/src/lang/random.ts +25 -0
  37. package/src/lang/string.ts +95 -0
  38. package/src/lang/time.ts +19 -0
  39. package/{lang/types.d.ts → src/lang/types.ts} +43 -23
  40. package/src/logging/adapt.ts +49 -0
  41. package/src/logging/formatters.ts +23 -0
  42. package/src/logging/index.ts +106 -0
  43. package/src/md5.ts +318 -0
  44. package/src/url.ts +185 -0
  45. package/src/validators/array.ts +97 -0
  46. package/src/validators/base.ts +145 -0
  47. package/src/validators/boolean.ts +21 -0
  48. package/src/validators/datetime.ts +39 -0
  49. package/src/validators/factory.ts +244 -0
  50. package/src/validators/index.ts +9 -0
  51. package/src/validators/number.ts +54 -0
  52. package/src/validators/object.ts +101 -0
  53. package/src/validators/one-of.ts +33 -0
  54. package/src/validators/string.ts +72 -0
  55. package/env-browser/device.d.ts +0 -24
  56. package/env-browser/device.js +0 -50
  57. package/env-browser/global.d.ts +0 -10
  58. package/env-browser/global.js +0 -15
  59. package/env-browser/load-script.d.ts +0 -5
  60. package/env-browser/load-script.js +0 -13
  61. package/env-browser/logging.d.ts +0 -18
  62. package/env-browser/logging.js +0 -49
  63. package/env-browser/manage-vconsole.d.ts +0 -16
  64. package/env-browser/manage-vconsole.js +0 -38
  65. package/env-node/crypto-random.d.ts +0 -13
  66. package/env-node/crypto-random.js +0 -28
  67. package/env-node/fs.d.ts +0 -19
  68. package/env-node/fs.js +0 -48
  69. package/env-node/index.d.ts +0 -5
  70. package/env-node/index.js +0 -5
  71. package/env-node/logging/handlers.d.ts +0 -58
  72. package/env-node/logging/handlers.js +0 -154
  73. package/env-node/logging/index.d.ts +0 -11
  74. package/env-node/logging/index.js +0 -14
  75. package/env-react/emotion.d.ts +0 -20
  76. package/env-react/emotion.jsx +0 -34
  77. package/env-service/controllers.d.ts +0 -30
  78. package/env-service/controllers.js +0 -41
  79. package/env-service/env-reader.d.ts +0 -55
  80. package/env-service/env-reader.js +0 -79
  81. package/env-service/index.d.ts +0 -6
  82. package/env-service/index.js +0 -6
  83. package/env-service/prisma/adapt-logging.d.ts +0 -21
  84. package/env-service/prisma/adapt-logging.js +0 -30
  85. package/env-service/prisma/extensions/exist.d.ts +0 -10
  86. package/env-service/prisma/extensions/exist.js +0 -16
  87. package/env-service/prisma/extensions/find-and-count.d.ts +0 -7
  88. package/env-service/prisma/extensions/find-and-count.js +0 -19
  89. package/env-service/prisma/extensions/soft-delete.d.ts +0 -52
  90. package/env-service/prisma/extensions/soft-delete.js +0 -123
  91. package/env-service/prisma/extensions/with-transaction.d.ts +0 -9
  92. package/env-service/prisma/extensions/with-transaction.js +0 -54
  93. package/env-service/prisma/index.d.ts +0 -6
  94. package/env-service/prisma/index.js +0 -6
  95. package/env-service/prisma/transaction-contexted.d.ts +0 -11
  96. package/env-service/prisma/transaction-contexted.js +0 -52
  97. package/env-service/redis-cache.d.ts +0 -39
  98. package/env-service/redis-cache.js +0 -116
  99. package/env-service/tasks.d.ts +0 -12
  100. package/env-service/tasks.js +0 -37
  101. package/index.d.ts +0 -3
  102. package/index.js +0 -3
  103. package/init-dayjs.d.ts +0 -2
  104. package/init-dayjs.js +0 -7
  105. package/lang/async.d.ts +0 -19
  106. package/lang/async.js +0 -34
  107. package/lang/index.d.ts +0 -7
  108. package/lang/index.js +0 -7
  109. package/lang/may-success.d.ts +0 -40
  110. package/lang/may-success.js +0 -27
  111. package/lang/object.d.ts +0 -5
  112. package/lang/object.js +0 -31
  113. package/lang/random.d.ts +0 -13
  114. package/lang/random.js +0 -24
  115. package/lang/string.d.ts +0 -29
  116. package/lang/string.js +0 -92
  117. package/lang/time.d.ts +0 -10
  118. package/lang/time.js +0 -18
  119. package/lang/types.js +0 -28
  120. package/logging/adapt.d.ts +0 -10
  121. package/logging/adapt.js +0 -43
  122. package/logging/formatters.d.ts +0 -10
  123. package/logging/formatters.js +0 -22
  124. package/logging/index.d.ts +0 -45
  125. package/logging/index.js +0 -90
  126. package/md5.d.ts +0 -30
  127. package/md5.js +0 -308
  128. package/url.d.ts +0 -77
  129. package/url.js +0 -149
  130. package/validators/array.d.ts +0 -30
  131. package/validators/array.js +0 -47
  132. package/validators/base.d.ts +0 -82
  133. package/validators/base.js +0 -42
  134. package/validators/boolean.d.ts +0 -3
  135. package/validators/boolean.js +0 -22
  136. package/validators/factory.d.ts +0 -66
  137. package/validators/factory.js +0 -109
  138. package/validators/index.d.ts +0 -8
  139. package/validators/index.js +0 -8
  140. package/validators/number.d.ts +0 -19
  141. package/validators/number.js +0 -26
  142. package/validators/object.d.ts +0 -28
  143. package/validators/object.js +0 -49
  144. package/validators/oneOf.d.ts +0 -10
  145. package/validators/oneOf.js +0 -15
  146. package/validators/string.d.ts +0 -22
  147. package/validators/string.js +0 -35
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 时间处理相关函数
3
+ */
4
+
5
+ /**
6
+ * 返回指定时间长度的 毫秒数
7
+ */
8
+ export function daysMS(n: number) {
9
+ return hoursMS(n * 24)
10
+ }
11
+ export function hoursMS(n: number) {
12
+ return minutesMS(n * 60)
13
+ }
14
+ export function minutesMS(n: number) {
15
+ return secondsMS(n * 60)
16
+ }
17
+ export function secondsMS(n: number) {
18
+ return n * 1000
19
+ }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * 对类型系统的辅助、补充
3
3
  */
4
+
4
5
  /**
5
6
  * 解决 TypeScript 中,数组字面量 [1, 'a'] 无法自动识别为 tuple 的问题
6
7
  *
@@ -11,17 +12,22 @@
11
12
  * https://github.com/microsoft/TypeScript/issues/27179
12
13
  * https://github.com/microsoft/TypeScript/issues/16656
13
14
  */
14
- export declare function tuple<T extends unknown[]>(...elements: T): T;
15
+ export function tuple<T extends unknown[]>(...elements: T) {
16
+ return elements
17
+ }
18
+
15
19
  /** 将一个对象中的指定 key 设为必须的 */
16
- export type RequiredFields<T, K extends keyof T> = Omit<T, K> & Pick<Required<T>, K>;
20
+ export type RequiredFields<T, K extends keyof T> = Omit<T, K> & Pick<Required<T>, K>
21
+
17
22
  /** 将一个对象中的指定 key 设为非必须的 */
18
- export type OptionalFields<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
23
+ export type OptionalFields<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
24
+
19
25
  /** 用 ReplaceT 中的字段定义代替 T 中的 */
20
- export type ReplaceFields<T, ReplaceT> = Omit<T, keyof ReplaceT> & ReplaceT;
26
+ export type ReplaceFields<T, ReplaceT> = Omit<T, keyof ReplaceT> & ReplaceT
27
+
21
28
  /** 获取一个对象所有 value 的集合 */
22
- export type ValueOf<T> = T extends {
23
- [_ in keyof T]: infer U;
24
- } ? U : never;
29
+ export type ValueOf<T> = T extends { [_ in keyof T]: infer U } ? U : never
30
+
25
31
  /**
26
32
  * 获取指定类型的 key 的集合
27
33
  * 可以解决 keyof 无法正确获取继承了 plain object interface 的类型的 key 的问题
@@ -32,32 +38,46 @@ export type ValueOf<T> = T extends {
32
38
  * KnownKeys<MyType> // 'a' | 'b'
33
39
  */
34
40
  export type KnownKeys<T> = ValueOf<{
35
- [K in keyof T]: string extends K ? never : number extends K ? never : K;
36
- }>;
41
+ [K in keyof T]: string extends K ? never : number extends K ? never : K
42
+ }>
43
+
37
44
  /** 排除对象中指定类型的项目 */
38
- export type ExcludePropertiesOfType<T, ExcludeValueT> = Pick<T, {
39
- [K in keyof T]: T[K] extends ExcludeValueT ? never : K;
40
- }[keyof T]>;
45
+ export type ExcludePropertiesOfType<T, ExcludeValueT> = Pick<
46
+ T,
47
+ { [K in keyof T]: T[K] extends ExcludeValueT ? never : K }[keyof T]
48
+ >
49
+
41
50
  /**
42
51
  * 生成不包含指定 key 的类型
43
52
  * 与 Omit<T, Keys> 的区别是
44
53
  */
45
- export type ExcludeKeys<T, ExcludeKeys> = Pick<T, {
46
- [K in keyof T]: K extends ExcludeKeys ? never : K;
47
- }[keyof T]>;
54
+ export type ExcludeKeys<T, ExcludeKeys> = Pick<
55
+ T,
56
+ { [K in keyof T]: K extends ExcludeKeys ? never : K }[keyof T]
57
+ >
58
+
48
59
  /** 排除对象的方法(仅保留属性) */
49
- export type ExcluceMethods<T> = ExcludePropertiesOfType<T, Function>;
60
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
61
+ export type ExcluceMethods<T> = ExcludePropertiesOfType<T, Function>
62
+
50
63
  /**
51
64
  * 确认变量是否有值
52
65
  * 注意:空字符串和数字 0 也会判定为没有值
53
66
  */
54
- declare function truthy(value: string | number | boolean | null | undefined): value is string | number | true;
55
- declare function truthy<T>(value: T | string | number | boolean | null | undefined): value is T | string | number | true;
56
- export { truthy };
67
+ function truthy(
68
+ value: string | number | boolean | null | undefined,
69
+ ): value is string | number | true
70
+ function truthy<T>(
71
+ value: T | string | number | boolean | null | undefined,
72
+ ): value is T | string | number | true
73
+ function truthy<T>(value: T | string | number | boolean | null | undefined) {
74
+ return value !== null && value !== undefined && value !== '' && value !== 0 && value !== false
75
+ }
76
+ export { truthy }
77
+
57
78
  /** 定义 JSON 数据 */
58
- export type JSONData = number | boolean | string | null | JSONData[] | {
59
- [key: string]: JSONData;
60
- };
79
+ export type JSONData = number | boolean | string | null | JSONData[] | { [key: string]: JSONData }
80
+
61
81
  /**
62
82
  * 有些场景不适合用 undefined 判断一个变量是否被赋值(例如它允许被赋值成 undefined)
63
83
  * 此时可以用这个 symbol 来做判断。
@@ -65,4 +85,4 @@ export type JSONData = number | boolean | string | null | JSONData[] | {
65
85
  * if (value === noValue) console.log('未赋值')
66
86
  * else console.log('已赋值', value)
67
87
  */
68
- export declare const noValue: unique symbol;
88
+ export const noValue = Symbol('no-value')
@@ -0,0 +1,49 @@
1
+ import { getLogger, type Logger } from './index.js'
2
+
3
+ interface Debug {
4
+ enable: (namespaces: string) => void
5
+ log: (...args: any[]) => any // eslint-disable-line @typescript-eslint/no-explicit-any
6
+ }
7
+
8
+ /**
9
+ * 适配 debug package
10
+ */
11
+ export function adaptDebugLib(debugLib: Debug, enable = '', logger?: Logger) {
12
+ // 不在 localStorage 里记录 debugLib enable 状态,
13
+ // 以解决 web worker 里读不到 localStorage 而无法启用 debugLib 日志的问题
14
+ const emulate = {
15
+ storage: {
16
+ data: {} as Record<string, string>,
17
+ getItem(name: string) {
18
+ return emulate.storage.data[name]
19
+ },
20
+ setItem(name: string, value: string) {
21
+ emulate.storage.data[name] = value
22
+ },
23
+ removeItem(name: string) {
24
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
25
+ delete emulate.storage.data[name]
26
+ },
27
+ },
28
+ save(namespaces: string) {
29
+ if (namespaces) emulate.storage.setItem('debug', namespaces)
30
+ else emulate.storage.removeItem('debug')
31
+ },
32
+ load() {
33
+ return emulate.storage.getItem('debug')
34
+ },
35
+ }
36
+ Object.assign(debugLib, emulate)
37
+
38
+ // 将 debugLib 日志转发给 logger
39
+ if (!logger) logger = getLogger('3rd-library')
40
+ debugLib.log = logger.debug.bind(logger)
41
+
42
+ if (enable) {
43
+ // 有些库(例如 prisma)重新实现了自己的 debug 库,且模仿 debug 也读取 DEBUG 环境变量。
44
+ // 这里除了设置 debug 库,顺便也适配这些遵循 debug 库模式的自定义库。
45
+ process.env.DEBUG = enable
46
+
47
+ debugLib.enable(enable)
48
+ }
49
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 日志常用数据的格式化函数
3
+ */
4
+ import { type LogInfo, LogLevel } from './index.js'
5
+
6
+ const formatters = {
7
+ time(info: LogInfo) {
8
+ return info.time.format('HH:mm:ss.SSS')
9
+ },
10
+ datetime(info: LogInfo) {
11
+ return info.time.format('YY-MM-DD HH:mm:ss.SSS')
12
+ },
13
+ level(info: LogInfo) {
14
+ const map = {
15
+ [LogLevel.Debug]: 'debug',
16
+ [LogLevel.Info]: 'info',
17
+ [LogLevel.Warning]: 'warn',
18
+ [LogLevel.Error]: 'error',
19
+ }
20
+ return map[info.level]
21
+ },
22
+ }
23
+ export default formatters
@@ -0,0 +1,106 @@
1
+ import dayjs, { type Dayjs } from 'dayjs'
2
+ export { default as formatters } from './formatters.js'
3
+ export * from './adapt.js'
4
+ import { initDayJs } from '../init-dayjs.js'
5
+
6
+ // 引入 logging 库会自动初始化 dayjs
7
+ initDayJs()
8
+
9
+ export enum LogLevel {
10
+ Debug = 1,
11
+ Info = 2,
12
+ Warning = 3,
13
+ Error = 4,
14
+ }
15
+
16
+ export const logLevelMap: Record<string, LogLevel> = {
17
+ debug: LogLevel.Debug,
18
+ info: LogLevel.Info,
19
+ warn: LogLevel.Warning,
20
+ warning: LogLevel.Warning,
21
+ err: LogLevel.Error,
22
+ error: LogLevel.Error,
23
+ }
24
+
25
+ export interface LogInfo {
26
+ logger: string // logger name;有多级 logger 的情况下,这是最初的 logger 名称
27
+ level: LogLevel
28
+ time: Dayjs
29
+ args: unknown[] // log content
30
+ }
31
+
32
+ export class LogHandler {
33
+ log(info: LogInfo) {} // eslint-disable-line @typescript-eslint/no-unused-vars
34
+ }
35
+
36
+ export class Logger {
37
+ level = LogLevel.Info
38
+ handlers = new Set<LogHandler>()
39
+
40
+ constructor(
41
+ public name = '',
42
+ public base: Logger | null = null, // 指定上级 logger,当前 logger 记录的日志也会传递给上级
43
+ ) {}
44
+
45
+ static getRealLevel(raw: LogLevel | string) {
46
+ if (typeof raw === 'string') {
47
+ raw = raw.toLowerCase()
48
+ if (logLevelMap[raw] === undefined) throw new Error('Not supported log level: ' + raw)
49
+ return logLevelMap[raw]!
50
+ }
51
+ return raw
52
+ }
53
+
54
+ setLevel(level: LogLevel | string) {
55
+ this.level = Logger.getRealLevel(level)
56
+ }
57
+
58
+ addHandler(handler: LogHandler) {
59
+ this.handlers.add(handler)
60
+ }
61
+
62
+ /**
63
+ * 创建一个以当前 logger 为 base 的 child logger
64
+ */
65
+ getChild(name: string) {
66
+ const fullname = this.name ? `${this.name}/${name}` : name
67
+ type Constructor = new (...args: ConstructorParameters<typeof Logger>) => Logger
68
+ // 这里加上 `as this` 才能让 TypeScript 判定,对继承了 Logger 的类调用此方法时,返回的是那个类而不是原始的 Logger 类的实例
69
+ return new (this.constructor as Constructor)(fullname, this) as this
70
+ }
71
+
72
+ log(level: LogLevel | string, args: unknown[]) {
73
+ level = Logger.getRealLevel(level)
74
+ this.logByInfo({ logger: this.name, level, time: dayjs(), args })
75
+ }
76
+ protected logByInfo(info: LogInfo) {
77
+ if (this.base) this.base.logByInfo(info)
78
+ if (this.level > info.level) return
79
+ for (const handler of this.handlers) {
80
+ handler.log(info)
81
+ }
82
+ }
83
+
84
+ debug(...args: any[]) {
85
+ this.log(LogLevel.Debug, args)
86
+ }
87
+ info(...args: any[]) {
88
+ this.log(LogLevel.Info, args)
89
+ }
90
+ warn(...args: any[]) {
91
+ this.log(LogLevel.Warning, args)
92
+ }
93
+ error(...args: any[]) {
94
+ this.log(LogLevel.Error, args)
95
+ }
96
+ }
97
+
98
+ /**
99
+ * 提供一套默认配置好的 logger
100
+ */
101
+ const defaultLogger = new Logger()
102
+ export { defaultLogger as logger }
103
+
104
+ export function getLogger(name: string) {
105
+ return defaultLogger.getChild(name)
106
+ }
package/src/md5.ts ADDED
@@ -0,0 +1,318 @@
1
+ /* eslint-disable no-multi-assign */
2
+ /**
3
+ * MD5 算法来自:https://github.com/emn178/js-md5
4
+ */
5
+
6
+ export function md5(content: string | ArrayBuffer) {
7
+ const md5 = new MD5()
8
+ md5.update(content)
9
+ return md5.hex()
10
+ }
11
+
12
+ // -------------------------------------------------------------------
13
+
14
+ /**
15
+ * 使用方法:
16
+ * const md5 = new MD5()
17
+ * md5.update(xxx) // 对于大文件,可以拆分开,多次调用 md5.update()
18
+ * const hash = md5.hex()
19
+ */
20
+ export class MD5 {
21
+ private readonly buffer8: Uint8Array
22
+ private readonly blocks: Uint32Array
23
+
24
+ private h0 = 0
25
+ private h1 = 0
26
+ private h2 = 0
27
+ private h3 = 0
28
+ private start = 0
29
+ private bytes = 0
30
+ private hBytes = 0
31
+ private lastByteIndex = 0
32
+
33
+ private finalized = false
34
+ private hashed = false
35
+ private first = true
36
+
37
+ constructor() {
38
+ const buffer = new ArrayBuffer(68)
39
+ this.buffer8 = new Uint8Array(buffer)
40
+ this.blocks = new Uint32Array(buffer)
41
+ }
42
+
43
+ update(message: string | number[] | Uint8Array | ArrayBuffer) {
44
+ if (this.finalized) return
45
+
46
+ if (message instanceof ArrayBuffer) {
47
+ message = new Uint8Array(message)
48
+ }
49
+ if (typeof message !== 'string' && !Array.isArray(message) && !ArrayBuffer.isView(message)) {
50
+ throw new Error('input is invalid type')
51
+ }
52
+
53
+ const length = message.length
54
+ const { blocks, buffer8 } = this
55
+
56
+ let code: number
57
+ let index = 0
58
+ let i: number
59
+
60
+ while (index < length) {
61
+ if (this.hashed) {
62
+ this.hashed = false
63
+ blocks[0] = blocks[16]!
64
+ // prettier-ignore
65
+ blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] =
66
+ blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] =
67
+ blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0
68
+ }
69
+
70
+ if (typeof message !== 'string') {
71
+ for (i = this.start; index < length && i < 64; ++index) {
72
+ buffer8[i++] = message[index]!
73
+ }
74
+ } else {
75
+ for (i = this.start; index < length && i < 64; ++index) {
76
+ code = message.charCodeAt(index)
77
+ if (code < 0x80) {
78
+ buffer8[i++] = code
79
+ } else if (code < 0x800) {
80
+ buffer8[i++] = 0xc0 | (code >> 6)
81
+ buffer8[i++] = 0x80 | (code & 0x3f)
82
+ } else if (code < 0xd800 || code >= 0xe000) {
83
+ buffer8[i++] = 0xe0 | (code >> 12)
84
+ buffer8[i++] = 0x80 | ((code >> 6) & 0x3f)
85
+ buffer8[i++] = 0x80 | (code & 0x3f)
86
+ } else {
87
+ code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff))
88
+ buffer8[i++] = 0xf0 | (code >> 18)
89
+ buffer8[i++] = 0x80 | ((code >> 12) & 0x3f)
90
+ buffer8[i++] = 0x80 | ((code >> 6) & 0x3f)
91
+ buffer8[i++] = 0x80 | (code & 0x3f)
92
+ }
93
+ }
94
+ }
95
+ this.lastByteIndex = i
96
+ this.bytes += i - this.start
97
+ if (i >= 64) {
98
+ this.start = i - 64
99
+ this.hash()
100
+ this.hashed = true
101
+ } else {
102
+ this.start = i
103
+ }
104
+ }
105
+ if (this.bytes > 4294967295) {
106
+ this.hBytes += (this.bytes / 4294967296) << 0
107
+ this.bytes = this.bytes % 4294967296
108
+ }
109
+ }
110
+
111
+ private finalize() {
112
+ if (this.finalized) return
113
+ this.finalized = true
114
+ const { blocks } = this
115
+ const i = this.lastByteIndex
116
+ const EXTRA = [128, 32768, 8388608, -2147483648]
117
+ blocks[i >> 2]! |= EXTRA[i & 3]!
118
+ if (i >= 56) {
119
+ if (!this.hashed) this.hash()
120
+ blocks[0] = blocks[16]!
121
+ // prettier-ignore
122
+ blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] =
123
+ blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] =
124
+ blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0
125
+ }
126
+ blocks[14] = this.bytes << 3
127
+ blocks[15] = (this.hBytes << 3) | (this.bytes >>> 29)
128
+ this.hash()
129
+ }
130
+
131
+ private hash() {
132
+ let a: number, b: number, c: number, d: number, bc: number, da: number
133
+ const { blocks } = this
134
+
135
+ if (this.first) {
136
+ a = blocks[0]! - 680876937
137
+ a = (((a << 7) | (a >>> 25)) - 271733879) << 0
138
+ d = (-1732584194 ^ (a & 2004318071)) + blocks[1]! - 117830708
139
+ d = (((d << 12) | (d >>> 20)) + a) << 0
140
+ c = (-271733879 ^ (d & (a ^ -271733879))) + blocks[2]! - 1126478375
141
+ c = (((c << 17) | (c >>> 15)) + d) << 0
142
+ b = (a ^ (c & (d ^ a))) + blocks[3]! - 1316259209
143
+ b = (((b << 22) | (b >>> 10)) + c) << 0
144
+ } else {
145
+ a = this.h0
146
+ b = this.h1
147
+ c = this.h2
148
+ d = this.h3
149
+ a += (d ^ (b & (c ^ d))) + blocks[0]! - 680876936
150
+ a = (((a << 7) | (a >>> 25)) + b) << 0
151
+ d += (c ^ (a & (b ^ c))) + blocks[1]! - 389564586
152
+ d = (((d << 12) | (d >>> 20)) + a) << 0
153
+ c += (b ^ (d & (a ^ b))) + blocks[2]! + 606105819
154
+ c = (((c << 17) | (c >>> 15)) + d) << 0
155
+ b += (a ^ (c & (d ^ a))) + blocks[3]! - 1044525330
156
+ b = (((b << 22) | (b >>> 10)) + c) << 0
157
+ }
158
+
159
+ a += (d ^ (b & (c ^ d))) + blocks[4]! - 176418897
160
+ a = (((a << 7) | (a >>> 25)) + b) << 0
161
+ d += (c ^ (a & (b ^ c))) + blocks[5]! + 1200080426
162
+ d = (((d << 12) | (d >>> 20)) + a) << 0
163
+ c += (b ^ (d & (a ^ b))) + blocks[6]! - 1473231341
164
+ c = (((c << 17) | (c >>> 15)) + d) << 0
165
+ b += (a ^ (c & (d ^ a))) + blocks[7]! - 45705983
166
+ b = (((b << 22) | (b >>> 10)) + c) << 0
167
+ a += (d ^ (b & (c ^ d))) + blocks[8]! + 1770035416
168
+ a = (((a << 7) | (a >>> 25)) + b) << 0
169
+ d += (c ^ (a & (b ^ c))) + blocks[9]! - 1958414417
170
+ d = (((d << 12) | (d >>> 20)) + a) << 0
171
+ c += (b ^ (d & (a ^ b))) + blocks[10]! - 42063
172
+ c = (((c << 17) | (c >>> 15)) + d) << 0
173
+ b += (a ^ (c & (d ^ a))) + blocks[11]! - 1990404162
174
+ b = (((b << 22) | (b >>> 10)) + c) << 0
175
+ a += (d ^ (b & (c ^ d))) + blocks[12]! + 1804603682
176
+ a = (((a << 7) | (a >>> 25)) + b) << 0
177
+ d += (c ^ (a & (b ^ c))) + blocks[13]! - 40341101
178
+ d = (((d << 12) | (d >>> 20)) + a) << 0
179
+ c += (b ^ (d & (a ^ b))) + blocks[14]! - 1502002290
180
+ c = (((c << 17) | (c >>> 15)) + d) << 0
181
+ b += (a ^ (c & (d ^ a))) + blocks[15]! + 1236535329
182
+ b = (((b << 22) | (b >>> 10)) + c) << 0
183
+ a += (c ^ (d & (b ^ c))) + blocks[1]! - 165796510
184
+ a = (((a << 5) | (a >>> 27)) + b) << 0
185
+ d += (b ^ (c & (a ^ b))) + blocks[6]! - 1069501632
186
+ d = (((d << 9) | (d >>> 23)) + a) << 0
187
+ c += (a ^ (b & (d ^ a))) + blocks[11]! + 643717713
188
+ c = (((c << 14) | (c >>> 18)) + d) << 0
189
+ b += (d ^ (a & (c ^ d))) + blocks[0]! - 373897302
190
+ b = (((b << 20) | (b >>> 12)) + c) << 0
191
+ a += (c ^ (d & (b ^ c))) + blocks[5]! - 701558691
192
+ a = (((a << 5) | (a >>> 27)) + b) << 0
193
+ d += (b ^ (c & (a ^ b))) + blocks[10]! + 38016083
194
+ d = (((d << 9) | (d >>> 23)) + a) << 0
195
+ c += (a ^ (b & (d ^ a))) + blocks[15]! - 660478335
196
+ c = (((c << 14) | (c >>> 18)) + d) << 0
197
+ b += (d ^ (a & (c ^ d))) + blocks[4]! - 405537848
198
+ b = (((b << 20) | (b >>> 12)) + c) << 0
199
+ a += (c ^ (d & (b ^ c))) + blocks[9]! + 568446438
200
+ a = (((a << 5) | (a >>> 27)) + b) << 0
201
+ d += (b ^ (c & (a ^ b))) + blocks[14]! - 1019803690
202
+ d = (((d << 9) | (d >>> 23)) + a) << 0
203
+ c += (a ^ (b & (d ^ a))) + blocks[3]! - 187363961
204
+ c = (((c << 14) | (c >>> 18)) + d) << 0
205
+ b += (d ^ (a & (c ^ d))) + blocks[8]! + 1163531501
206
+ b = (((b << 20) | (b >>> 12)) + c) << 0
207
+ a += (c ^ (d & (b ^ c))) + blocks[13]! - 1444681467
208
+ a = (((a << 5) | (a >>> 27)) + b) << 0
209
+ d += (b ^ (c & (a ^ b))) + blocks[2]! - 51403784
210
+ d = (((d << 9) | (d >>> 23)) + a) << 0
211
+ c += (a ^ (b & (d ^ a))) + blocks[7]! + 1735328473
212
+ c = (((c << 14) | (c >>> 18)) + d) << 0
213
+ b += (d ^ (a & (c ^ d))) + blocks[12]! - 1926607734
214
+ b = (((b << 20) | (b >>> 12)) + c) << 0
215
+ bc = b ^ c
216
+ a += (bc ^ d) + blocks[5]! - 378558
217
+ a = (((a << 4) | (a >>> 28)) + b) << 0
218
+ d += (bc ^ a) + blocks[8]! - 2022574463
219
+ d = (((d << 11) | (d >>> 21)) + a) << 0
220
+ da = d ^ a
221
+ c += (da ^ b) + blocks[11]! + 1839030562
222
+ c = (((c << 16) | (c >>> 16)) + d) << 0
223
+ b += (da ^ c) + blocks[14]! - 35309556
224
+ b = (((b << 23) | (b >>> 9)) + c) << 0
225
+ bc = b ^ c
226
+ a += (bc ^ d) + blocks[1]! - 1530992060
227
+ a = (((a << 4) | (a >>> 28)) + b) << 0
228
+ d += (bc ^ a) + blocks[4]! + 1272893353
229
+ d = (((d << 11) | (d >>> 21)) + a) << 0
230
+ da = d ^ a
231
+ c += (da ^ b) + blocks[7]! - 155497632
232
+ c = (((c << 16) | (c >>> 16)) + d) << 0
233
+ b += (da ^ c) + blocks[10]! - 1094730640
234
+ b = (((b << 23) | (b >>> 9)) + c) << 0
235
+ bc = b ^ c
236
+ a += (bc ^ d) + blocks[13]! + 681279174
237
+ a = (((a << 4) | (a >>> 28)) + b) << 0
238
+ d += (bc ^ a) + blocks[0]! - 358537222
239
+ d = (((d << 11) | (d >>> 21)) + a) << 0
240
+ da = d ^ a
241
+ c += (da ^ b) + blocks[3]! - 722521979
242
+ c = (((c << 16) | (c >>> 16)) + d) << 0
243
+ b += (da ^ c) + blocks[6]! + 76029189
244
+ b = (((b << 23) | (b >>> 9)) + c) << 0
245
+ bc = b ^ c
246
+ a += (bc ^ d) + blocks[9]! - 640364487
247
+ a = (((a << 4) | (a >>> 28)) + b) << 0
248
+ d += (bc ^ a) + blocks[12]! - 421815835
249
+ d = (((d << 11) | (d >>> 21)) + a) << 0
250
+ da = d ^ a
251
+ c += (da ^ b) + blocks[15]! + 530742520
252
+ c = (((c << 16) | (c >>> 16)) + d) << 0
253
+ b += (da ^ c) + blocks[2]! - 995338651
254
+ b = (((b << 23) | (b >>> 9)) + c) << 0
255
+ a += (c ^ (b | ~d)) + blocks[0]! - 198630844
256
+ a = (((a << 6) | (a >>> 26)) + b) << 0
257
+ d += (b ^ (a | ~c)) + blocks[7]! + 1126891415
258
+ d = (((d << 10) | (d >>> 22)) + a) << 0
259
+ c += (a ^ (d | ~b)) + blocks[14]! - 1416354905
260
+ c = (((c << 15) | (c >>> 17)) + d) << 0
261
+ b += (d ^ (c | ~a)) + blocks[5]! - 57434055
262
+ b = (((b << 21) | (b >>> 11)) + c) << 0
263
+ a += (c ^ (b | ~d)) + blocks[12]! + 1700485571
264
+ a = (((a << 6) | (a >>> 26)) + b) << 0
265
+ d += (b ^ (a | ~c)) + blocks[3]! - 1894986606
266
+ d = (((d << 10) | (d >>> 22)) + a) << 0
267
+ c += (a ^ (d | ~b)) + blocks[10]! - 1051523
268
+ c = (((c << 15) | (c >>> 17)) + d) << 0
269
+ b += (d ^ (c | ~a)) + blocks[1]! - 2054922799
270
+ b = (((b << 21) | (b >>> 11)) + c) << 0
271
+ a += (c ^ (b | ~d)) + blocks[8]! + 1873313359
272
+ a = (((a << 6) | (a >>> 26)) + b) << 0
273
+ d += (b ^ (a | ~c)) + blocks[15]! - 30611744
274
+ d = (((d << 10) | (d >>> 22)) + a) << 0
275
+ c += (a ^ (d | ~b)) + blocks[6]! - 1560198380
276
+ c = (((c << 15) | (c >>> 17)) + d) << 0
277
+ b += (d ^ (c | ~a)) + blocks[13]! + 1309151649
278
+ b = (((b << 21) | (b >>> 11)) + c) << 0
279
+ a += (c ^ (b | ~d)) + blocks[4]! - 145523070
280
+ a = (((a << 6) | (a >>> 26)) + b) << 0
281
+ d += (b ^ (a | ~c)) + blocks[11]! - 1120210379
282
+ d = (((d << 10) | (d >>> 22)) + a) << 0
283
+ c += (a ^ (d | ~b)) + blocks[2]! + 718787259
284
+ c = (((c << 15) | (c >>> 17)) + d) << 0
285
+ b += (d ^ (c | ~a)) + blocks[9]! - 343485551
286
+ b = (((b << 21) | (b >>> 11)) + c) << 0
287
+
288
+ if (this.first) {
289
+ this.h0 = (a + 1732584193) << 0
290
+ this.h1 = (b - 271733879) << 0
291
+ this.h2 = (c - 1732584194) << 0
292
+ this.h3 = (d + 271733878) << 0
293
+ this.first = false
294
+ } else {
295
+ this.h0 = (this.h0 + a) << 0
296
+ this.h1 = (this.h1 + b) << 0
297
+ this.h2 = (this.h2 + c) << 0
298
+ this.h3 = (this.h3 + d) << 0
299
+ }
300
+ }
301
+
302
+ hex() {
303
+ this.finalize()
304
+
305
+ const { h0, h1, h2, h3 } = this
306
+ const HEX_CHARS = '0123456789abcdef'.split('')
307
+ return (
308
+ // prettier-ignore
309
+ HEX_CHARS[(h0 >> 4) & 0x0f]! + HEX_CHARS[h0 & 0x0f]! + HEX_CHARS[(h0 >> 12) & 0x0f]! + HEX_CHARS[(h0 >> 8) & 0x0f]! + HEX_CHARS[(h0 >> 20) & 0x0f]! +
310
+ HEX_CHARS[(h0 >> 16) & 0x0f]! + HEX_CHARS[(h0 >> 28) & 0x0f]! + HEX_CHARS[(h0 >> 24) & 0x0f]! + HEX_CHARS[(h1 >> 4) & 0x0f]! + HEX_CHARS[h1 & 0x0f]! +
311
+ HEX_CHARS[(h1 >> 12) & 0x0f]! + HEX_CHARS[(h1 >> 8) & 0x0f]! + HEX_CHARS[(h1 >> 20) & 0x0f]! + HEX_CHARS[(h1 >> 16) & 0x0f]! + HEX_CHARS[(h1 >> 28) & 0x0f]! +
312
+ HEX_CHARS[(h1 >> 24) & 0x0f]! + HEX_CHARS[(h2 >> 4) & 0x0f]! + HEX_CHARS[h2 & 0x0f]! + HEX_CHARS[(h2 >> 12) & 0x0f]! + HEX_CHARS[(h2 >> 8) & 0x0f]! +
313
+ HEX_CHARS[(h2 >> 20) & 0x0f]! + HEX_CHARS[(h2 >> 16) & 0x0f]! + HEX_CHARS[(h2 >> 28) & 0x0f]! + HEX_CHARS[(h2 >> 24) & 0x0f]! + HEX_CHARS[(h3 >> 4) & 0x0f]! +
314
+ HEX_CHARS[h3 & 0x0f]! + HEX_CHARS[(h3 >> 12) & 0x0f]! + HEX_CHARS[(h3 >> 8) & 0x0f]! + HEX_CHARS[(h3 >> 20) & 0x0f]! + HEX_CHARS[(h3 >> 16) & 0x0f]! +
315
+ HEX_CHARS[(h3 >> 28) & 0x0f]! + HEX_CHARS[(h3 >> 24) & 0x0f]!
316
+ )
317
+ }
318
+ }