@scalar/helpers 0.4.1 → 0.4.3
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/CHANGELOG.md +13 -0
- package/dist/array/add-to-map-array.js +7 -8
- package/dist/array/is-defined.js +12 -5
- package/dist/array/sort-by-order.js +60 -18
- package/dist/consts/content-types.js +13 -14
- package/dist/dom/freeze-element.js +56 -42
- package/dist/dom/get-selector.d.ts +7 -0
- package/dist/dom/get-selector.d.ts.map +1 -0
- package/dist/dom/get-selector.js +31 -0
- package/dist/dom/scroll-to-id.js +33 -27
- package/dist/file/json2xml.js +79 -61
- package/dist/formatters/format-bytes.d.ts +7 -0
- package/dist/formatters/format-bytes.d.ts.map +1 -0
- package/dist/formatters/format-bytes.js +18 -0
- package/dist/formatters/format-milliseconds.d.ts +6 -0
- package/dist/formatters/format-milliseconds.d.ts.map +1 -0
- package/dist/formatters/format-milliseconds.js +10 -0
- package/dist/general/create-limiter.js +47 -31
- package/dist/general/debounce.js +86 -66
- package/dist/general/extract-config-secrets.js +29 -27
- package/dist/general/has-modifier.js +9 -8
- package/dist/general/is-mac-os.js +23 -21
- package/dist/http/can-method-have-body.js +4 -6
- package/dist/http/http-info.js +63 -61
- package/dist/http/http-methods.js +4 -7
- package/dist/http/http-status-codes.js +316 -320
- package/dist/http/is-http-method.js +3 -6
- package/dist/http/normalize-http-method.js +19 -19
- package/dist/json/escape-json-pointer.js +6 -5
- package/dist/json/parse-json-pointer-segments.js +11 -6
- package/dist/json/pretty-print-json.d.ts +9 -0
- package/dist/json/pretty-print-json.d.ts.map +1 -0
- package/dist/json/pretty-print-json.js +42 -0
- package/dist/json/unescape-json-pointer.js +7 -5
- package/dist/markdown/get-markdown-headings.d.ts +11 -0
- package/dist/markdown/get-markdown-headings.d.ts.map +1 -0
- package/dist/markdown/get-markdown-headings.js +99 -0
- package/dist/node/path.js +168 -138
- package/dist/object/get-value-at-path.js +17 -11
- package/dist/object/is-object.js +24 -10
- package/dist/object/local-storage.js +50 -42
- package/dist/object/object-entries.js +2 -5
- package/dist/object/object-keys.js +5 -5
- package/dist/object/object-replace.js +13 -12
- package/dist/object/omit-undefined-values.js +18 -18
- package/dist/object/prevent-pollution.js +27 -10
- package/dist/object/to-json-compatible.js +71 -62
- package/dist/queue/queue.js +103 -84
- package/dist/regex/find-variables.js +13 -8
- package/dist/regex/regex-helpers.js +17 -17
- package/dist/regex/replace-variables.js +21 -19
- package/dist/string/camel-to-title.js +10 -5
- package/dist/string/capitalize.js +5 -5
- package/dist/string/create-hash.js +19 -16
- package/dist/string/generate-hash.js +153 -127
- package/dist/string/iterate-title.js +13 -11
- package/dist/string/truncate.js +16 -9
- package/dist/testing/console-spies.js +19 -24
- package/dist/testing/measure.js +42 -19
- package/dist/testing/measure.test-d.js +12 -9
- package/dist/testing/sleep.js +5 -5
- package/dist/url/ensure-protocol.js +8 -10
- package/dist/url/extract-server-from-path.js +53 -28
- package/dist/url/is-local-url.js +24 -18
- package/dist/url/is-relative-path.js +15 -13
- package/dist/url/is-valid-url.js +17 -10
- package/dist/url/make-url-absolute.js +39 -28
- package/dist/url/merge-urls.js +74 -52
- package/dist/url/redirect-to-proxy.js +68 -39
- package/package.json +15 -9
- package/dist/array/add-to-map-array.js.map +0 -7
- package/dist/array/is-defined.js.map +0 -7
- package/dist/array/sort-by-order.js.map +0 -7
- package/dist/consts/content-types.js.map +0 -7
- package/dist/dom/freeze-element.js.map +0 -7
- package/dist/dom/scroll-to-id.js.map +0 -7
- package/dist/file/json2xml.js.map +0 -7
- package/dist/general/create-limiter.js.map +0 -7
- package/dist/general/debounce.js.map +0 -7
- package/dist/general/extract-config-secrets.js.map +0 -7
- package/dist/general/has-modifier.js.map +0 -7
- package/dist/general/is-mac-os.js.map +0 -7
- package/dist/http/can-method-have-body.js.map +0 -7
- package/dist/http/http-info.js.map +0 -7
- package/dist/http/http-methods.js.map +0 -7
- package/dist/http/http-status-codes.js.map +0 -7
- package/dist/http/is-http-method.js.map +0 -7
- package/dist/http/normalize-http-method.js.map +0 -7
- package/dist/json/escape-json-pointer.js.map +0 -7
- package/dist/json/parse-json-pointer-segments.js.map +0 -7
- package/dist/json/unescape-json-pointer.js.map +0 -7
- package/dist/node/path.js.map +0 -7
- package/dist/object/get-value-at-path.js.map +0 -7
- package/dist/object/is-object.js.map +0 -7
- package/dist/object/local-storage.js.map +0 -7
- package/dist/object/object-entries.js.map +0 -7
- package/dist/object/object-keys.js.map +0 -7
- package/dist/object/object-replace.js.map +0 -7
- package/dist/object/omit-undefined-values.js.map +0 -7
- package/dist/object/prevent-pollution.js.map +0 -7
- package/dist/object/to-json-compatible.js.map +0 -7
- package/dist/queue/queue.js.map +0 -7
- package/dist/regex/find-variables.js.map +0 -7
- package/dist/regex/regex-helpers.js.map +0 -7
- package/dist/regex/replace-variables.js.map +0 -7
- package/dist/string/camel-to-title.js.map +0 -7
- package/dist/string/capitalize.js.map +0 -7
- package/dist/string/create-hash.js.map +0 -7
- package/dist/string/generate-hash.js.map +0 -7
- package/dist/string/iterate-title.js.map +0 -7
- package/dist/string/truncate.js.map +0 -7
- package/dist/testing/console-spies.js.map +0 -7
- package/dist/testing/measure.js.map +0 -7
- package/dist/testing/measure.test-d.js.map +0 -7
- package/dist/testing/sleep.js.map +0 -7
- package/dist/url/ensure-protocol.js.map +0 -7
- package/dist/url/extract-server-from-path.js.map +0 -7
- package/dist/url/is-local-url.js.map +0 -7
- package/dist/url/is-relative-path.js.map +0 -7
- package/dist/url/is-valid-url.js.map +0 -7
- package/dist/url/make-url-absolute.js.map +0 -7
- package/dist/url/merge-urls.js.map +0 -7
- package/dist/url/redirect-to-proxy.js.map +0 -7
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Collection of regular expressions used throughout the application.
|
|
3
|
+
* These patterns handle URL parsing, variable detection, and reference path extraction.
|
|
4
|
+
*/
|
|
5
|
+
export const REGEX = {
|
|
6
|
+
/** Checks for a valid scheme */
|
|
7
|
+
PROTOCOL: /^(?:https?|ftp|file|mailto|tel|data|wss?)*:\/\//,
|
|
8
|
+
/** Finds multiple slashes after the scheme to replace with a single slash */
|
|
9
|
+
MULTIPLE_SLASHES: /(?<!:)\/{2,}/g,
|
|
10
|
+
/** Finds all variables wrapped in {{double}} */
|
|
11
|
+
VARIABLES: /{{((?:[^{}]|{[^{}]*})*)}}/g,
|
|
12
|
+
/** Finds all variables wrapped in {single} */
|
|
13
|
+
PATH: /(?:{)([^{}]+)}(?!})/g,
|
|
14
|
+
/** Finds the name of the schema from the ref path */
|
|
15
|
+
REF_NAME: /\/([^\/]+)$/,
|
|
16
|
+
/** Finds template variables in multiple formats: {{var}}, {var}, or :var */
|
|
17
|
+
TEMPLATE_VARIABLE: /{{\s*([^}\s]+?)\s*}}|{\s*([^}\s]+?)\s*}|:\b[\w.]+\b/g,
|
|
14
18
|
};
|
|
15
|
-
export {
|
|
16
|
-
REGEX
|
|
17
|
-
};
|
|
18
|
-
//# sourceMappingURL=regex-helpers.js.map
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import { REGEX } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { REGEX } from '../regex/regex-helpers.js';
|
|
2
|
+
/**
|
|
3
|
+
* This function takes a string and replaces both {single} and {{double}} curly brace variables with given values.
|
|
4
|
+
* Use the replacePathVariables and replaceEnvVariables functions if you only need to replace one type of variable.
|
|
5
|
+
*/
|
|
6
|
+
export function replaceVariables(value, variablesOrCallback) {
|
|
7
|
+
// Replace all variables (example: {{ baseurl }} with an HTML tag)
|
|
8
|
+
const doubleCurlyBrackets = /{{\s*([\w.-]+)\s*}}/g;
|
|
9
|
+
const singleCurlyBrackets = /{\s*([\w.-]+)\s*}/g;
|
|
10
|
+
const callback = (_, match) => {
|
|
11
|
+
if (typeof variablesOrCallback === 'function') {
|
|
12
|
+
return variablesOrCallback(match);
|
|
13
|
+
}
|
|
14
|
+
return variablesOrCallback[match]?.toString() || `{${match}}`;
|
|
15
|
+
};
|
|
16
|
+
// Loop through all matches and replace the match with the variable value
|
|
17
|
+
return value.replace(doubleCurlyBrackets, callback).replace(singleCurlyBrackets, callback);
|
|
12
18
|
}
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
replacePathVariables,
|
|
18
|
-
replaceVariables
|
|
19
|
-
};
|
|
20
|
-
//# sourceMappingURL=replace-variables.js.map
|
|
19
|
+
/** Replace {path} variables with their values */
|
|
20
|
+
export const replacePathVariables = (path, variables = {}) => path.replace(REGEX.PATH, (match, key) => variables[key] ?? match);
|
|
21
|
+
/** Replace {{env}} variables with their values */
|
|
22
|
+
export const replaceEnvVariables = (path, variables = {}) => path.replace(REGEX.VARIABLES, (match, key) => variables[key] ?? match);
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Converts a camelCase string to Title Words with spaces
|
|
3
|
+
*
|
|
4
|
+
* @param camelStr - MUST be in camelCase or this might not work
|
|
5
|
+
*/
|
|
6
|
+
export const camelToTitleWords = (camelStr = '') => camelStr
|
|
7
|
+
.replace(/([A-Z]{2,})/g, ' $1') // Add space before consecutive capitals
|
|
8
|
+
.replace(/([A-Z])(?=[a-z])/g, ' $1') // Add space before single capital followed by lowercase
|
|
9
|
+
.replace(/^./, (str) => str.toUpperCase()) // Capitalize first letter
|
|
10
|
+
.trim();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Capitalize first letter
|
|
3
|
+
* You should normally do this in css, only use this if you have to
|
|
4
|
+
*/
|
|
5
|
+
export const capitalize = (str = '') => (str[0]?.toUpperCase() ?? '') + str.slice(1);
|
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Simple 32 bit non-secure hash from a string input
|
|
3
|
+
*
|
|
4
|
+
* @deprecated Please use generateHash from ./generate-hash.ts instead
|
|
5
|
+
*
|
|
6
|
+
* @see https://stackoverflow.com/a/7616484/1624255
|
|
7
|
+
*/
|
|
8
|
+
export const createHash = (input) => {
|
|
9
|
+
let chr = 0;
|
|
10
|
+
let hash = 0;
|
|
11
|
+
let i = 0;
|
|
12
|
+
if (!input?.length) {
|
|
13
|
+
return hash;
|
|
14
|
+
}
|
|
15
|
+
for (i = 0; i < input.length; i++) {
|
|
16
|
+
chr = input.charCodeAt(i);
|
|
17
|
+
hash = (hash << 5) - hash + chr;
|
|
18
|
+
hash |= 0; // Convert to 32bit integer
|
|
19
|
+
}
|
|
6
20
|
return hash;
|
|
7
|
-
}
|
|
8
|
-
for (i = 0; i < input.length; i++) {
|
|
9
|
-
chr = input.charCodeAt(i);
|
|
10
|
-
hash = (hash << 5) - hash + chr;
|
|
11
|
-
hash |= 0;
|
|
12
|
-
}
|
|
13
|
-
return hash;
|
|
14
21
|
};
|
|
15
|
-
export {
|
|
16
|
-
createHash
|
|
17
|
-
};
|
|
18
|
-
//# sourceMappingURL=create-hash.js.map
|
|
@@ -1,130 +1,156 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
1
|
+
/**
|
|
2
|
+
* MurmurHash3 implementation
|
|
3
|
+
*
|
|
4
|
+
* Generate a hash from a string using the MurmurHash3 algorithm
|
|
5
|
+
* Provides 64-bit hash output with excellent speed and distribution
|
|
6
|
+
*
|
|
7
|
+
* We had to move away from xxhash-wasm since it was causing issues with content security policy (CSP) violations.
|
|
8
|
+
*
|
|
9
|
+
* We cannot use crypto.subtle because it is only available in secure contexts (HTTPS) or on localhost.
|
|
10
|
+
*
|
|
11
|
+
* @param input - The string to hash
|
|
12
|
+
* @returns The 64-bit hash of the input string as a 16-character hex string
|
|
13
|
+
*/
|
|
14
|
+
export const generateHash = (input) => {
|
|
15
|
+
const seed = 0;
|
|
16
|
+
// Working with 64-bit values using pairs of 32-bit integers
|
|
17
|
+
let h1 = seed;
|
|
18
|
+
let h2 = seed;
|
|
19
|
+
const len = input.length;
|
|
20
|
+
const remainder = len & 15; // len % 16
|
|
21
|
+
const bytes = len - remainder;
|
|
22
|
+
const c1 = 0x87c37b91;
|
|
23
|
+
const c2 = 0x4cf5ad43;
|
|
24
|
+
const c3 = 0x52dce729;
|
|
25
|
+
const c4 = 0x38495ab5;
|
|
26
|
+
// Process 16-byte chunks
|
|
27
|
+
for (let i = 0; i < bytes; i += 16) {
|
|
28
|
+
let k1 = (input.charCodeAt(i) & 0xff) |
|
|
29
|
+
((input.charCodeAt(i + 1) & 0xff) << 8) |
|
|
30
|
+
((input.charCodeAt(i + 2) & 0xff) << 16) |
|
|
31
|
+
((input.charCodeAt(i + 3) & 0xff) << 24);
|
|
32
|
+
let k2 = (input.charCodeAt(i + 4) & 0xff) |
|
|
33
|
+
((input.charCodeAt(i + 5) & 0xff) << 8) |
|
|
34
|
+
((input.charCodeAt(i + 6) & 0xff) << 16) |
|
|
35
|
+
((input.charCodeAt(i + 7) & 0xff) << 24);
|
|
36
|
+
let k3 = (input.charCodeAt(i + 8) & 0xff) |
|
|
37
|
+
((input.charCodeAt(i + 9) & 0xff) << 8) |
|
|
38
|
+
((input.charCodeAt(i + 10) & 0xff) << 16) |
|
|
39
|
+
((input.charCodeAt(i + 11) & 0xff) << 24);
|
|
40
|
+
let k4 = (input.charCodeAt(i + 12) & 0xff) |
|
|
41
|
+
((input.charCodeAt(i + 13) & 0xff) << 8) |
|
|
42
|
+
((input.charCodeAt(i + 14) & 0xff) << 16) |
|
|
43
|
+
((input.charCodeAt(i + 15) & 0xff) << 24);
|
|
44
|
+
k1 = Math.imul(k1, c1);
|
|
45
|
+
k1 = (k1 << 15) | (k1 >>> 17);
|
|
46
|
+
k1 = Math.imul(k1, c2);
|
|
47
|
+
h1 ^= k1;
|
|
48
|
+
h1 = (h1 << 13) | (h1 >>> 19);
|
|
49
|
+
h1 = Math.imul(h1, 5) + 0xe6546b64;
|
|
50
|
+
k2 = Math.imul(k2, c2);
|
|
51
|
+
k2 = (k2 << 16) | (k2 >>> 16);
|
|
52
|
+
k2 = Math.imul(k2, c3);
|
|
53
|
+
h2 ^= k2;
|
|
54
|
+
h2 = (h2 << 17) | (h2 >>> 15);
|
|
55
|
+
h2 = Math.imul(h2, 5) + 0x1b873593;
|
|
56
|
+
k3 = Math.imul(k3, c3);
|
|
57
|
+
k3 = (k3 << 17) | (k3 >>> 15);
|
|
58
|
+
k3 = Math.imul(k3, c4);
|
|
59
|
+
h1 ^= k3;
|
|
60
|
+
h1 = (h1 << 15) | (h1 >>> 17);
|
|
61
|
+
h1 = Math.imul(h1, 5) + 0x52dce729;
|
|
62
|
+
k4 = Math.imul(k4, c4);
|
|
63
|
+
k4 = (k4 << 18) | (k4 >>> 14);
|
|
64
|
+
k4 = Math.imul(k4, c1);
|
|
65
|
+
h2 ^= k4;
|
|
66
|
+
h2 = (h2 << 13) | (h2 >>> 19);
|
|
67
|
+
h2 = Math.imul(h2, 5) + 0x38495ab5;
|
|
49
68
|
}
|
|
50
|
-
|
|
51
|
-
|
|
69
|
+
// Process remaining bytes
|
|
70
|
+
if (remainder > 0) {
|
|
71
|
+
let k1 = 0;
|
|
72
|
+
let k2 = 0;
|
|
73
|
+
let k3 = 0;
|
|
74
|
+
let k4 = 0;
|
|
75
|
+
if (remainder >= 15) {
|
|
76
|
+
k4 ^= (input.charCodeAt(bytes + 14) & 0xff) << 16;
|
|
77
|
+
}
|
|
78
|
+
if (remainder >= 14) {
|
|
79
|
+
k4 ^= (input.charCodeAt(bytes + 13) & 0xff) << 8;
|
|
80
|
+
}
|
|
81
|
+
if (remainder >= 13) {
|
|
82
|
+
k4 ^= input.charCodeAt(bytes + 12) & 0xff;
|
|
83
|
+
k4 = Math.imul(k4, c4);
|
|
84
|
+
k4 = (k4 << 18) | (k4 >>> 14);
|
|
85
|
+
k4 = Math.imul(k4, c1);
|
|
86
|
+
h2 ^= k4;
|
|
87
|
+
}
|
|
88
|
+
if (remainder >= 12) {
|
|
89
|
+
k3 ^= (input.charCodeAt(bytes + 11) & 0xff) << 24;
|
|
90
|
+
}
|
|
91
|
+
if (remainder >= 11) {
|
|
92
|
+
k3 ^= (input.charCodeAt(bytes + 10) & 0xff) << 16;
|
|
93
|
+
}
|
|
94
|
+
if (remainder >= 10) {
|
|
95
|
+
k3 ^= (input.charCodeAt(bytes + 9) & 0xff) << 8;
|
|
96
|
+
}
|
|
97
|
+
if (remainder >= 9) {
|
|
98
|
+
k3 ^= input.charCodeAt(bytes + 8) & 0xff;
|
|
99
|
+
k3 = Math.imul(k3, c3);
|
|
100
|
+
k3 = (k3 << 17) | (k3 >>> 15);
|
|
101
|
+
k3 = Math.imul(k3, c4);
|
|
102
|
+
h1 ^= k3;
|
|
103
|
+
}
|
|
104
|
+
if (remainder >= 8) {
|
|
105
|
+
k2 ^= (input.charCodeAt(bytes + 7) & 0xff) << 24;
|
|
106
|
+
}
|
|
107
|
+
if (remainder >= 7) {
|
|
108
|
+
k2 ^= (input.charCodeAt(bytes + 6) & 0xff) << 16;
|
|
109
|
+
}
|
|
110
|
+
if (remainder >= 6) {
|
|
111
|
+
k2 ^= (input.charCodeAt(bytes + 5) & 0xff) << 8;
|
|
112
|
+
}
|
|
113
|
+
if (remainder >= 5) {
|
|
114
|
+
k2 ^= input.charCodeAt(bytes + 4) & 0xff;
|
|
115
|
+
k2 = Math.imul(k2, c2);
|
|
116
|
+
k2 = (k2 << 16) | (k2 >>> 16);
|
|
117
|
+
k2 = Math.imul(k2, c3);
|
|
118
|
+
h2 ^= k2;
|
|
119
|
+
}
|
|
120
|
+
if (remainder >= 4) {
|
|
121
|
+
k1 ^= (input.charCodeAt(bytes + 3) & 0xff) << 24;
|
|
122
|
+
}
|
|
123
|
+
if (remainder >= 3) {
|
|
124
|
+
k1 ^= (input.charCodeAt(bytes + 2) & 0xff) << 16;
|
|
125
|
+
}
|
|
126
|
+
if (remainder >= 2) {
|
|
127
|
+
k1 ^= (input.charCodeAt(bytes + 1) & 0xff) << 8;
|
|
128
|
+
}
|
|
129
|
+
if (remainder >= 1) {
|
|
130
|
+
k1 ^= input.charCodeAt(bytes) & 0xff;
|
|
131
|
+
k1 = Math.imul(k1, c1);
|
|
132
|
+
k1 = (k1 << 15) | (k1 >>> 17);
|
|
133
|
+
k1 = Math.imul(k1, c2);
|
|
134
|
+
h1 ^= k1;
|
|
135
|
+
}
|
|
52
136
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
k3 = k3 << 17 | k3 >>> 15;
|
|
73
|
-
k3 = Math.imul(k3, c4);
|
|
74
|
-
h1 ^= k3;
|
|
75
|
-
}
|
|
76
|
-
if (remainder >= 8) {
|
|
77
|
-
k2 ^= (input.charCodeAt(bytes + 7) & 255) << 24;
|
|
78
|
-
}
|
|
79
|
-
if (remainder >= 7) {
|
|
80
|
-
k2 ^= (input.charCodeAt(bytes + 6) & 255) << 16;
|
|
81
|
-
}
|
|
82
|
-
if (remainder >= 6) {
|
|
83
|
-
k2 ^= (input.charCodeAt(bytes + 5) & 255) << 8;
|
|
84
|
-
}
|
|
85
|
-
if (remainder >= 5) {
|
|
86
|
-
k2 ^= input.charCodeAt(bytes + 4) & 255;
|
|
87
|
-
k2 = Math.imul(k2, c2);
|
|
88
|
-
k2 = k2 << 16 | k2 >>> 16;
|
|
89
|
-
k2 = Math.imul(k2, c3);
|
|
90
|
-
h2 ^= k2;
|
|
91
|
-
}
|
|
92
|
-
if (remainder >= 4) {
|
|
93
|
-
k1 ^= (input.charCodeAt(bytes + 3) & 255) << 24;
|
|
94
|
-
}
|
|
95
|
-
if (remainder >= 3) {
|
|
96
|
-
k1 ^= (input.charCodeAt(bytes + 2) & 255) << 16;
|
|
97
|
-
}
|
|
98
|
-
if (remainder >= 2) {
|
|
99
|
-
k1 ^= (input.charCodeAt(bytes + 1) & 255) << 8;
|
|
100
|
-
}
|
|
101
|
-
if (remainder >= 1) {
|
|
102
|
-
k1 ^= input.charCodeAt(bytes) & 255;
|
|
103
|
-
k1 = Math.imul(k1, c1);
|
|
104
|
-
k1 = k1 << 15 | k1 >>> 17;
|
|
105
|
-
k1 = Math.imul(k1, c2);
|
|
106
|
-
h1 ^= k1;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
h1 ^= len;
|
|
110
|
-
h2 ^= len;
|
|
111
|
-
h1 += h2;
|
|
112
|
-
h2 += h1;
|
|
113
|
-
h1 ^= h1 >>> 16;
|
|
114
|
-
h1 = Math.imul(h1, 2246822507);
|
|
115
|
-
h1 ^= h1 >>> 13;
|
|
116
|
-
h1 = Math.imul(h1, 3266489909);
|
|
117
|
-
h1 ^= h1 >>> 16;
|
|
118
|
-
h2 ^= h2 >>> 16;
|
|
119
|
-
h2 = Math.imul(h2, 2246822507);
|
|
120
|
-
h2 ^= h2 >>> 13;
|
|
121
|
-
h2 = Math.imul(h2, 3266489909);
|
|
122
|
-
h2 ^= h2 >>> 16;
|
|
123
|
-
h1 += h2;
|
|
124
|
-
h2 += h1;
|
|
125
|
-
return (h1 >>> 0).toString(16).padStart(8, "0") + (h2 >>> 0).toString(16).padStart(8, "0");
|
|
126
|
-
};
|
|
127
|
-
export {
|
|
128
|
-
generateHash
|
|
137
|
+
// Finalization
|
|
138
|
+
h1 ^= len;
|
|
139
|
+
h2 ^= len;
|
|
140
|
+
h1 += h2;
|
|
141
|
+
h2 += h1;
|
|
142
|
+
h1 ^= h1 >>> 16;
|
|
143
|
+
h1 = Math.imul(h1, 0x85ebca6b);
|
|
144
|
+
h1 ^= h1 >>> 13;
|
|
145
|
+
h1 = Math.imul(h1, 0xc2b2ae35);
|
|
146
|
+
h1 ^= h1 >>> 16;
|
|
147
|
+
h2 ^= h2 >>> 16;
|
|
148
|
+
h2 = Math.imul(h2, 0x85ebca6b);
|
|
149
|
+
h2 ^= h2 >>> 13;
|
|
150
|
+
h2 = Math.imul(h2, 0xc2b2ae35);
|
|
151
|
+
h2 ^= h2 >>> 16;
|
|
152
|
+
h1 += h2;
|
|
153
|
+
h2 += h1;
|
|
154
|
+
// Return 64-bit hash as hex string (two 32-bit values concatenated)
|
|
155
|
+
return (h1 >>> 0).toString(16).padStart(8, '0') + (h2 >>> 0).toString(16).padStart(8, '0');
|
|
129
156
|
};
|
|
130
|
-
//# sourceMappingURL=generate-hash.js.map
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Check for duplicate titles, and iterate title
|
|
3
|
+
*/
|
|
4
|
+
export const iterateTitle = (title, checkDuplicates, separator = ' #') => {
|
|
5
|
+
// If the title is not a duplicate return
|
|
6
|
+
if (!checkDuplicates(title)) {
|
|
7
|
+
return title;
|
|
8
|
+
}
|
|
9
|
+
const split = title.split(separator);
|
|
10
|
+
const newTitle = split.length > 1
|
|
11
|
+
? `${split.slice(0, -1).join()}${separator}${Number(split.at(-1)) + 1}`
|
|
12
|
+
: `${split.join()}${separator}2`;
|
|
13
|
+
return iterateTitle(newTitle, checkDuplicates, separator);
|
|
8
14
|
};
|
|
9
|
-
export {
|
|
10
|
-
iterateTitle
|
|
11
|
-
};
|
|
12
|
-
//# sourceMappingURL=iterate-title.js.map
|
package/dist/string/truncate.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Truncates a string to a specified length and adds an ellipsis if it's longer in JS
|
|
3
|
+
*
|
|
4
|
+
* @param str - The string to truncate
|
|
5
|
+
* @param maxLength - The maximum length before truncation (default: 18)
|
|
6
|
+
* @returns The truncated string with ellipsis if needed
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* truncate('Very long name that needs truncation') // 'Very long name th…'
|
|
10
|
+
* truncate('Short') // 'Short'
|
|
11
|
+
*/
|
|
12
|
+
export const truncate = (str, maxLength = 18) => {
|
|
13
|
+
if (str.length <= maxLength) {
|
|
14
|
+
return str;
|
|
15
|
+
}
|
|
16
|
+
return str.slice(0, maxLength) + '…';
|
|
6
17
|
};
|
|
7
|
-
export {
|
|
8
|
-
truncate
|
|
9
|
-
};
|
|
10
|
-
//# sourceMappingURL=truncate.js.map
|
|
@@ -1,25 +1,20 @@
|
|
|
1
|
-
import { vi } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { vi } from 'vitest';
|
|
2
|
+
/** Spy on console.warn */
|
|
3
|
+
export const consoleWarnSpy = vi.spyOn(console, 'warn');
|
|
4
|
+
export let isConsoleWarnEnabled = false;
|
|
5
|
+
/** Spy on console.error */
|
|
6
|
+
export const consoleErrorSpy = vi.spyOn(console, 'error');
|
|
7
|
+
export let isConsoleErrorEnabled = false;
|
|
8
|
+
/** Reset the spies */
|
|
9
|
+
export const resetConsoleSpies = () => {
|
|
10
|
+
consoleWarnSpy.mockClear();
|
|
11
|
+
consoleErrorSpy.mockClear();
|
|
9
12
|
};
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
disableConsoleWarn,
|
|
19
|
-
enableConsoleError,
|
|
20
|
-
enableConsoleWarn,
|
|
21
|
-
isConsoleErrorEnabled,
|
|
22
|
-
isConsoleWarnEnabled,
|
|
23
|
-
resetConsoleSpies
|
|
24
|
-
};
|
|
25
|
-
//# sourceMappingURL=console-spies.js.map
|
|
13
|
+
/** Helper to re-enable console warn checks */
|
|
14
|
+
export const enableConsoleWarn = () => (isConsoleWarnEnabled = true);
|
|
15
|
+
/** Helper to disable console warn checks */
|
|
16
|
+
export const disableConsoleWarn = () => (isConsoleWarnEnabled = false);
|
|
17
|
+
/** Helper to enable console error checks */
|
|
18
|
+
export const enableConsoleError = () => (isConsoleErrorEnabled = true);
|
|
19
|
+
/** Helper to disable console error checks */
|
|
20
|
+
export const disableConsoleError = () => (isConsoleErrorEnabled = false);
|
package/dist/testing/measure.js
CHANGED
|
@@ -1,21 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Measures the execution time of a function and logs it.
|
|
3
|
+
*
|
|
4
|
+
* Works only with sync functions and returns the result of the measured function.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* // Sync function
|
|
10
|
+
* const result = measureSync('computation', () => {
|
|
11
|
+
* return heavyComputation()
|
|
12
|
+
* })
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export const measureSync = (name, fn) => {
|
|
16
|
+
const start = performance.now();
|
|
17
|
+
const result = fn();
|
|
18
|
+
const end = performance.now();
|
|
19
|
+
const duration = Math.round(end - start);
|
|
20
|
+
console.info(`${name}: ${duration} ms`);
|
|
21
|
+
return result;
|
|
8
22
|
};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Measures the execution time of an async function and logs it.
|
|
25
|
+
*
|
|
26
|
+
* Works only with async functions and returns the result of the measured function.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
*
|
|
30
|
+
* ```ts
|
|
31
|
+
* // Async function
|
|
32
|
+
* const result = await measure('api-call', async () => {
|
|
33
|
+
* return await fetchData()
|
|
34
|
+
* })
|
|
35
|
+
* ````
|
|
36
|
+
*/
|
|
37
|
+
export const measureAsync = async (name, fn) => {
|
|
38
|
+
const start = performance.now();
|
|
39
|
+
const result = await fn();
|
|
40
|
+
const end = performance.now();
|
|
41
|
+
const duration = Math.round(end - start);
|
|
42
|
+
console.info(`${name}: ${duration} ms`);
|
|
43
|
+
return result;
|
|
16
44
|
};
|
|
17
|
-
export {
|
|
18
|
-
measureAsync,
|
|
19
|
-
measureSync
|
|
20
|
-
};
|
|
21
|
-
//# sourceMappingURL=measure.js.map
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { describe, vi } from
|
|
2
|
-
import { measureAsync, measureSync } from
|
|
1
|
+
import { describe, vi } from 'vitest';
|
|
2
|
+
import { measureAsync, measureSync } from './measure.js';
|
|
3
3
|
const asyncFunction = vi.fn();
|
|
4
|
-
describe(
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
describe('measureAsync types', async () => {
|
|
5
|
+
// works with async methods
|
|
6
|
+
await measureAsync('test', asyncFunction);
|
|
7
|
+
// @ts-expect-error should error because `fn` doesn't return a Promise
|
|
8
|
+
await measureAsync('test', () => 1);
|
|
7
9
|
});
|
|
8
|
-
describe(
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
describe('measureSync types', () => {
|
|
11
|
+
// works with sync methods
|
|
12
|
+
measureSync('test', () => 1);
|
|
13
|
+
// @ts-expect-error should error because `fn` doesn't return a Promise
|
|
14
|
+
measureSync('test', asyncFunction);
|
|
11
15
|
});
|
|
12
|
-
//# sourceMappingURL=measure.test-d.js.map
|
package/dist/testing/sleep.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Little helper for sleeping for x milliseconds
|
|
3
|
+
* an async await friendly setTimeout
|
|
4
|
+
*/
|
|
5
|
+
export const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|