@wener/utils 1.1.11 → 1.1.13

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 (95) hide show
  1. package/dist/cjs/globalThis-ee7c1669.js +2 -0
  2. package/dist/cjs/globalThis-ee7c1669.js.map +1 -0
  3. package/dist/cjs/index.cjs +5 -5
  4. package/dist/cjs/index.cjs.map +1 -1
  5. package/dist/cjs/server.cjs +1 -1
  6. package/dist/cjs/server.cjs.map +1 -1
  7. package/dist/esm/globalThis-000611c3.js +2 -0
  8. package/dist/esm/globalThis-000611c3.js.map +1 -0
  9. package/dist/esm/index.js +4 -4
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/esm/server.js +1 -1
  12. package/dist/esm/server.js.map +1 -1
  13. package/dist/system/globalThis-7bba6592.js +2 -0
  14. package/dist/system/globalThis-7bba6592.js.map +1 -0
  15. package/dist/system/index.js +5 -5
  16. package/dist/system/index.js.map +1 -1
  17. package/dist/system/server.js +1 -1
  18. package/dist/system/server.js.map +1 -1
  19. package/lib/asyncs/AsyncInterval.js +1 -1
  20. package/lib/asyncs/AsyncInterval.js.map +1 -1
  21. package/lib/asyncs/timeout.js +3 -1
  22. package/lib/asyncs/timeout.js.map +1 -1
  23. package/lib/browsers/copy.js +2 -1
  24. package/lib/browsers/copy.js.map +1 -1
  25. package/lib/browsers/download.js +3 -1
  26. package/lib/browsers/download.js.map +1 -1
  27. package/lib/browsers/getFileFromDataTransfer.js +3 -2
  28. package/lib/browsers/getFileFromDataTransfer.js.map +1 -1
  29. package/lib/browsers/loaders.js +6 -2
  30. package/lib/browsers/loaders.js.map +1 -1
  31. package/lib/crypto/getRandomValues.js +7 -4
  32. package/lib/crypto/getRandomValues.js.map +1 -1
  33. package/lib/crypto/pem/pem.js +3 -2
  34. package/lib/crypto/pem/pem.js.map +1 -1
  35. package/lib/crypto/randomUUID.js +4 -1
  36. package/lib/crypto/randomUUID.js.map +1 -1
  37. package/lib/crypto/ulid.js +3 -3
  38. package/lib/crypto/ulid.js.map +1 -1
  39. package/lib/i18n/createTranslate.js +2 -1
  40. package/lib/i18n/createTranslate.js.map +1 -1
  41. package/lib/index.js +2 -0
  42. package/lib/index.js.map +1 -1
  43. package/lib/io/ArrayBuffers.js +166 -142
  44. package/lib/io/ArrayBuffers.js.map +1 -1
  45. package/lib/io/Buffer.js +6 -5
  46. package/lib/io/Buffer.js.map +1 -1
  47. package/lib/io/isBuffer.js +2 -1
  48. package/lib/io/isBuffer.js.map +1 -1
  49. package/lib/io/isTransferable.js +3 -1
  50. package/lib/io/isTransferable.js.map +1 -1
  51. package/lib/isomorphics/getGlobalThis.js.map +1 -1
  52. package/lib/isomorphics/globalThis.js +6 -0
  53. package/lib/isomorphics/globalThis.js.map +1 -0
  54. package/lib/isomorphics/structuredClone.js +1 -0
  55. package/lib/isomorphics/structuredClone.js.map +1 -1
  56. package/lib/langs/parseBoolean.js.map +1 -1
  57. package/lib/libs/ms.js +117 -0
  58. package/lib/libs/ms.js.map +1 -0
  59. package/lib/logging/createLogger.js +17 -6
  60. package/lib/logging/createLogger.js.map +1 -1
  61. package/lib/maths/random.js +2 -1
  62. package/lib/maths/random.js.map +1 -1
  63. package/lib/modules/parseModuleId.js +2 -1
  64. package/lib/modules/parseModuleId.js.map +1 -1
  65. package/lib/servers/createProxyFetch.js +3 -1
  66. package/lib/servers/createProxyFetch.js.map +1 -1
  67. package/lib/servers/polyfillCrypto.js +2 -0
  68. package/lib/servers/polyfillCrypto.js.map +1 -1
  69. package/lib/servers/polyfillFetch.js.map +1 -1
  70. package/lib/servers/polyfillJsDom.js +2 -0
  71. package/lib/servers/polyfillJsDom.js.map +1 -1
  72. package/package.json +2 -1
  73. package/src/asyncs/timeout.ts +1 -1
  74. package/src/browsers/copy.ts +1 -1
  75. package/src/browsers/download.ts +1 -1
  76. package/src/browsers/loaders.ts +2 -2
  77. package/src/crypto/getRandomValues.ts +1 -0
  78. package/src/crypto/randomUUID.ts +2 -0
  79. package/src/i18n/createTranslate.ts +2 -1
  80. package/src/index.ts +4 -0
  81. package/src/io/ArrayBuffers.ts +1 -0
  82. package/src/io/isTransferable.ts +2 -0
  83. package/src/isomorphics/getGlobalThis.ts +3 -1
  84. package/src/isomorphics/globalThis.ts +3 -0
  85. package/src/isomorphics/structuredClone.ts +1 -0
  86. package/src/langs/parseBoolean.ts +1 -1
  87. package/src/libs/README.md +1 -0
  88. package/src/libs/ms.ts +205 -0
  89. package/src/logging/createLogger.ts +5 -5
  90. package/src/objects/set.test.ts +1 -1
  91. package/src/servers/createProxyFetch.ts +2 -1
  92. package/src/servers/polyfillCrypto.ts +3 -1
  93. package/src/servers/polyfillFetch.ts +1 -0
  94. package/src/servers/polyfillJsDom.ts +1 -0
  95. package/src/servers/polyfillWebSocket.ts +15 -0
package/src/libs/ms.ts ADDED
@@ -0,0 +1,205 @@
1
+ // Helpers.
2
+ const s = 1000;
3
+ const m = s * 60;
4
+ const h = m * 60;
5
+ const d = h * 24;
6
+ const w = d * 7;
7
+ const y = d * 365.25;
8
+
9
+ type Unit =
10
+ | 'Years'
11
+ | 'Year'
12
+ | 'Yrs'
13
+ | 'Yr'
14
+ | 'Y'
15
+ | 'Weeks'
16
+ | 'Week'
17
+ | 'W'
18
+ | 'Days'
19
+ | 'Day'
20
+ | 'D'
21
+ | 'Hours'
22
+ | 'Hour'
23
+ | 'Hrs'
24
+ | 'Hr'
25
+ | 'H'
26
+ | 'Minutes'
27
+ | 'Minute'
28
+ | 'Mins'
29
+ | 'Min'
30
+ | 'M'
31
+ | 'Seconds'
32
+ | 'Second'
33
+ | 'Secs'
34
+ | 'Sec'
35
+ | 's'
36
+ | 'Milliseconds'
37
+ | 'Millisecond'
38
+ | 'Msecs'
39
+ | 'Msec'
40
+ | 'Ms';
41
+
42
+ type UnitAnyCase = Unit | Uppercase<Unit> | Lowercase<Unit>;
43
+
44
+ export type StringValue = `${number}` | `${number}${UnitAnyCase}` | `${number} ${UnitAnyCase}`;
45
+
46
+ interface Options {
47
+ /**
48
+ * Set to `true` to use verbose formatting. Defaults to `false`.
49
+ */
50
+ long?: boolean;
51
+ }
52
+
53
+ /**
54
+ * Parse or format the given value.
55
+ *
56
+ * @param value - The string or number to convert
57
+ * @param options - Options for the conversion
58
+ * @throws Error if `value` is not a non-empty string or a number
59
+ */
60
+ function msFn(value: StringValue, options?: Options): number;
61
+ function msFn(value: number, options?: Options): string;
62
+ function msFn(value: StringValue | number, options?: Options): number | string {
63
+ try {
64
+ if (typeof value === 'string' && value.length > 0) {
65
+ return parse(value);
66
+ } else if (typeof value === 'number' && isFinite(value)) {
67
+ return options?.long ? fmtLong(value) : fmtShort(value);
68
+ }
69
+ throw new Error('Value is not a string or number.');
70
+ } catch (error) {
71
+ const message = isError(error)
72
+ ? `${error.message}. value=${JSON.stringify(value)}`
73
+ : 'An unknown error has occurred.';
74
+ throw new Error(message);
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Parse the given string and return milliseconds.
80
+ *
81
+ * @param str - A string to parse to milliseconds
82
+ * @returns The parsed value in milliseconds, or `NaN` if the string can't be
83
+ * parsed
84
+ */
85
+ function parse(str: string): number {
86
+ if (str.length > 100) {
87
+ throw new Error('Value exceeds the maximum length of 100 characters.');
88
+ }
89
+ const match =
90
+ /^(?<value>-?(?:\d+)?\.?\d+) *(?<type>milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
91
+ str,
92
+ );
93
+ // Named capture groups need to be manually typed today.
94
+ // https://github.com/microsoft/TypeScript/issues/32098
95
+ const groups = match?.groups as { value: string; type?: string } | undefined;
96
+ if (!groups) {
97
+ return NaN;
98
+ }
99
+ const n = parseFloat(groups.value);
100
+ const type = (groups.type || 'ms').toLowerCase() as Lowercase<Unit>;
101
+ switch (type) {
102
+ case 'years':
103
+ case 'year':
104
+ case 'yrs':
105
+ case 'yr':
106
+ case 'y':
107
+ return n * y;
108
+ case 'weeks':
109
+ case 'week':
110
+ case 'w':
111
+ return n * w;
112
+ case 'days':
113
+ case 'day':
114
+ case 'd':
115
+ return n * d;
116
+ case 'hours':
117
+ case 'hour':
118
+ case 'hrs':
119
+ case 'hr':
120
+ case 'h':
121
+ return n * h;
122
+ case 'minutes':
123
+ case 'minute':
124
+ case 'mins':
125
+ case 'min':
126
+ case 'm':
127
+ return n * m;
128
+ case 'seconds':
129
+ case 'second':
130
+ case 'secs':
131
+ case 'sec':
132
+ case 's':
133
+ return n * s;
134
+ case 'milliseconds':
135
+ case 'millisecond':
136
+ case 'msecs':
137
+ case 'msec':
138
+ case 'ms':
139
+ return n;
140
+ default:
141
+ // This should never occur.
142
+ throw new Error(`The unit ${type as string} was matched, but no matching case exists.`);
143
+ }
144
+ }
145
+
146
+ // eslint-disable-next-line import/no-default-export
147
+ export default msFn;
148
+
149
+ /**
150
+ * Short format for `ms`.
151
+ */
152
+ function fmtShort(ms: number): StringValue {
153
+ const msAbs = Math.abs(ms);
154
+ if (msAbs >= d) {
155
+ return `${Math.round(ms / d)}d`;
156
+ }
157
+ if (msAbs >= h) {
158
+ return `${Math.round(ms / h)}h`;
159
+ }
160
+ if (msAbs >= m) {
161
+ return `${Math.round(ms / m)}m`;
162
+ }
163
+ if (msAbs >= s) {
164
+ return `${Math.round(ms / s)}s`;
165
+ }
166
+ return `${ms}ms`;
167
+ }
168
+
169
+ /**
170
+ * Long format for `ms`.
171
+ */
172
+ function fmtLong(ms: number): StringValue {
173
+ const msAbs = Math.abs(ms);
174
+ if (msAbs >= d) {
175
+ return plural(ms, msAbs, d, 'day');
176
+ }
177
+ if (msAbs >= h) {
178
+ return plural(ms, msAbs, h, 'hour');
179
+ }
180
+ if (msAbs >= m) {
181
+ return plural(ms, msAbs, m, 'minute');
182
+ }
183
+ if (msAbs >= s) {
184
+ return plural(ms, msAbs, s, 'second');
185
+ }
186
+ return `${ms} ms`;
187
+ }
188
+
189
+ /**
190
+ * Pluralization helper.
191
+ */
192
+ function plural(ms: number, msAbs: number, n: number, name: string): StringValue {
193
+ const isPlural = msAbs >= n * 1.5;
194
+ return `${Math.round(ms / n)} ${name}${isPlural ? 's' : ''}` as StringValue;
195
+ }
196
+
197
+ /**
198
+ * A type guard for errors.
199
+ *
200
+ * @param value - The value to test
201
+ * @returns A boolean `true` if the provided value is an Error-like object
202
+ */
203
+ function isError(value: unknown): value is Error {
204
+ return typeof value === 'object' && value !== null && 'message' in value;
205
+ }
@@ -12,11 +12,11 @@ export function createLogger(
12
12
  context: object = {},
13
13
  ): LoggerWithChild {
14
14
  return {
15
- trace: (...values) => write({ ...context, level: 'trace', values }),
16
- debug: (...values) => write({ ...context, level: 'debug', values }),
17
- info: (...values) => write({ ...context, level: 'info', values }),
18
- warn: (...values) => write({ ...context, level: 'warn', values }),
19
- error: (...values) => write({ ...context, level: 'error', values }),
15
+ trace: (...values) => { write({ ...context, level: 'trace', values }); },
16
+ debug: (...values) => { write({ ...context, level: 'debug', values }); },
17
+ info: (...values) => { write({ ...context, level: 'info', values }); },
18
+ warn: (...values) => { write({ ...context, level: 'warn', values }); },
19
+ error: (...values) => { write({ ...context, level: 'error', values }); },
20
20
  child: (ctx) => createLogger(write, { ...context, ...ctx }),
21
21
  };
22
22
  }
@@ -28,7 +28,7 @@ test('set objects', (t) => {
28
28
  const orig = set;
29
29
 
30
30
  function run(isMerge: boolean) {
31
- const set = (a: any, b: any, c: any) => orig(a, b, c, isMerge);
31
+ const set = (a: any, b: any, c: any) => { orig(a, b, c, isMerge); };
32
32
  const verb = isMerge ? 'merge' : 'overwrite';
33
33
  objects(`should ${verb} existing object value :: simple`, () => {
34
34
  const { input } = prepare({
@@ -1,4 +1,5 @@
1
- import { FetchLike } from '../fetch';
1
+ import { type FetchLike } from '../fetch';
2
+ import { globalThis } from '../isomorphics/globalThis';
2
3
 
3
4
  export function createProxyFetch(proxy?: string, fetch?: FetchLike): FetchLike {
4
5
  if (!proxy) {
@@ -1,7 +1,9 @@
1
+ import { globalThis } from '../isomorphics/globalThis';
2
+
1
3
  export async function polyfillCrypto() {
2
4
  if ('crypto' in globalThis) {
3
5
  return false;
4
6
  }
5
- globalThis.crypto = (await import('node:crypto')).webcrypto as Crypto;
7
+ (globalThis as any).crypto = (await import('node:crypto')).webcrypto as Crypto;
6
8
  return true;
7
9
  }
@@ -20,6 +20,7 @@ export function polyfillFetch(nodeFetch?: typeof import('node-fetch')): MaybePro
20
20
  Blob,
21
21
  File,
22
22
  });
23
+ // abort controller
23
24
  return true;
24
25
  }
25
26
  return import('node-fetch').then((v) => polyfillFetch(v));
@@ -1,4 +1,5 @@
1
1
  import type { ConstructorOptions, ResourceLoaderConstructorOptions } from 'jsdom';
2
+ import { globalThis } from '../isomorphics/globalThis';
2
3
 
3
4
  export async function polyfillJsDom() {
4
5
  if (typeof window !== 'undefined') {
@@ -0,0 +1,15 @@
1
+ import type { MaybePromise } from '../asyncs/MaybePromise';
2
+ import { globalThis } from '../isomorphics/globalThis';
3
+
4
+ export function polyfillWebSocket(ws: any): boolean;
5
+ export function polyfillWebSocket(ws?: undefined): Promise<boolean>;
6
+ export function polyfillWebSocket(ws?: any): MaybePromise<boolean> {
7
+ if ('WebSocket' in globalThis) {
8
+ return false;
9
+ }
10
+ if (ws) {
11
+ const { WebSocket } = ws;
12
+ Object.assign(globalThis, { WebSocket });
13
+ }
14
+ return import('ws').then((ws) => polyfillWebSocket(ws));
15
+ }