@scalar/helpers 0.4.1 → 0.4.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.
- package/CHANGELOG.md +6 -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/scroll-to-id.js +33 -27
- package/dist/file/json2xml.js +79 -61
- 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/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 +5 -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,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Type safe version of Object.keys
|
|
3
|
+
* Can probably remove this whenever typescript adds it
|
|
4
|
+
*/
|
|
5
|
+
export const objectKeys = (obj) => Object.keys(obj);
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
// TODO: This is a copy of org/packages/helpers/src/objects/merge.ts
|
|
2
|
+
/**
|
|
3
|
+
* Overwrite a target object a new replacement object handling removed keys
|
|
4
|
+
*/
|
|
5
|
+
export const objectReplace = (target, replacement) => {
|
|
6
|
+
// Clear any keys that have been removed in the replacement
|
|
7
|
+
Object.keys(target).forEach((key) => {
|
|
8
|
+
if (!Object.hasOwn(replacement, key)) {
|
|
9
|
+
delete target[key];
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.assign(target, replacement);
|
|
13
|
+
return target;
|
|
9
14
|
};
|
|
10
|
-
export {
|
|
11
|
-
objectReplace
|
|
12
|
-
};
|
|
13
|
-
//# sourceMappingURL=object-replace.js.map
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Removes undefined values from an object.
|
|
3
|
+
*
|
|
4
|
+
* Can be used as a transform function for any Zod schema.
|
|
5
|
+
*/
|
|
6
|
+
export const omitUndefinedValues = (data) => {
|
|
7
|
+
// Handle arrays specially
|
|
8
|
+
if (Array.isArray(data)) {
|
|
9
|
+
return data.map((item) => typeof item === 'object' && item !== null ? omitUndefinedValues(item) : item);
|
|
10
|
+
}
|
|
11
|
+
return Object.fromEntries(Object.entries(data)
|
|
12
|
+
.filter(([_, value]) => value !== undefined)
|
|
13
|
+
.map(([key, value]) => {
|
|
14
|
+
if (typeof value === 'object' && value !== null) {
|
|
15
|
+
return [key, omitUndefinedValues(value)];
|
|
16
|
+
}
|
|
17
|
+
return [key, value];
|
|
18
|
+
}));
|
|
15
19
|
};
|
|
16
|
-
export {
|
|
17
|
-
omitUndefinedValues
|
|
18
|
-
};
|
|
19
|
-
//# sourceMappingURL=omit-undefined-values.js.map
|
|
@@ -1,11 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Set of dangerous keys that can be used for prototype pollution attacks.
|
|
3
|
+
* These keys should never be used as property names in dynamic object operations.
|
|
4
|
+
*/
|
|
5
|
+
const PROTOTYPE_POLLUTION_KEYS = new Set(['__proto__', 'prototype', 'constructor']);
|
|
6
|
+
/**
|
|
7
|
+
* Validates that a key is safe to use and does not pose a prototype pollution risk.
|
|
8
|
+
* Throws an error if a dangerous key is detected.
|
|
9
|
+
*
|
|
10
|
+
* @param key - The key to validate
|
|
11
|
+
* @param context - Optional context string to help identify where the validation failed
|
|
12
|
+
* @throws {Error} If the key matches a known prototype pollution vector
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* preventPollution('__proto__') // throws Error
|
|
17
|
+
* preventPollution('safeName') // passes
|
|
18
|
+
* preventPollution('constructor', 'operation update') // throws Error with context
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export const preventPollution = (key, context) => {
|
|
22
|
+
if (PROTOTYPE_POLLUTION_KEYS.has(key)) {
|
|
23
|
+
const errorMessage = context
|
|
24
|
+
? `Prototype pollution key detected: "${key}" in ${context}`
|
|
25
|
+
: `Prototype pollution key detected: "${key}"`;
|
|
26
|
+
throw new Error(errorMessage);
|
|
27
|
+
}
|
|
7
28
|
};
|
|
8
|
-
export {
|
|
9
|
-
preventPollution
|
|
10
|
-
};
|
|
11
|
-
//# sourceMappingURL=prevent-pollution.js.map
|
|
@@ -1,68 +1,77 @@
|
|
|
1
|
-
import { escapeJsonPointer } from
|
|
2
|
-
import { Queue } from
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
import { escapeJsonPointer } from '../json/escape-json-pointer.js';
|
|
2
|
+
import { Queue } from '../queue/queue.js';
|
|
3
|
+
/**
|
|
4
|
+
* Traverses an object or array, returning a deep copy in which circular references are replaced
|
|
5
|
+
* by JSON Reference objects of the form: `{ $ref: "#/path/to/original" }`.
|
|
6
|
+
* This allows safe serialization of objects with cycles, following the JSON Reference convention (RFC 6901).
|
|
7
|
+
* An optional `prefix` for the `$ref` path can be provided via options.
|
|
8
|
+
*
|
|
9
|
+
* @param obj - The input object or array to process
|
|
10
|
+
* @param options - Optional configuration; you can set a prefix for $ref pointers
|
|
11
|
+
* @returns A new object or array, with all circular references replaced by $ref pointers
|
|
12
|
+
*/
|
|
13
|
+
export const toJsonCompatible = (obj, options = {}) => {
|
|
14
|
+
const { prefix = '', cache = new WeakMap() } = options;
|
|
15
|
+
const toRef = (path) => ({ $ref: `#${path ?? ''}` });
|
|
16
|
+
// Primitives and null are returned as-is
|
|
17
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
18
|
+
return obj;
|
|
18
19
|
}
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
const rootPath = prefix;
|
|
21
|
+
cache.set(obj, rootPath);
|
|
22
|
+
const rootResult = Array.isArray(obj) ? new Array(obj.length) : {};
|
|
23
|
+
const queue = new Queue();
|
|
24
|
+
queue.enqueue({ node: obj, result: rootResult, path: rootPath });
|
|
25
|
+
while (!queue.isEmpty()) {
|
|
26
|
+
const frame = queue.dequeue();
|
|
27
|
+
if (!frame) {
|
|
28
|
+
continue;
|
|
26
29
|
}
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
const { node, result, path } = frame;
|
|
31
|
+
// Handle arrays (preserve sparse arrays like Array#map does)
|
|
32
|
+
if (Array.isArray(node)) {
|
|
33
|
+
const input = node;
|
|
34
|
+
const out = result;
|
|
35
|
+
for (let index = 0; index < input.length; index++) {
|
|
36
|
+
if (!(index in input)) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const item = input[index];
|
|
40
|
+
const itemPath = `${path}/${index}`;
|
|
41
|
+
if (typeof item !== 'object' || item === null) {
|
|
42
|
+
out[index] = item;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const existingPath = cache.get(item);
|
|
46
|
+
if (existingPath !== undefined) {
|
|
47
|
+
out[index] = toRef(existingPath);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
cache.set(item, itemPath);
|
|
51
|
+
const childResult = Array.isArray(item) ? new Array(item.length) : {};
|
|
52
|
+
out[index] = childResult;
|
|
53
|
+
queue.enqueue({ node: item, result: childResult, path: itemPath });
|
|
54
|
+
}
|
|
55
|
+
continue;
|
|
32
56
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
57
|
+
// Handle objects - create a new object with processed values
|
|
58
|
+
const out = result;
|
|
59
|
+
for (const [key, value] of Object.entries(node)) {
|
|
60
|
+
const valuePath = `${path}/${escapeJsonPointer(key)}`;
|
|
61
|
+
if (typeof value !== 'object' || value === null) {
|
|
62
|
+
out[key] = value;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const existingPath = cache.get(value);
|
|
66
|
+
if (existingPath !== undefined) {
|
|
67
|
+
out[key] = toRef(existingPath);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
cache.set(value, valuePath);
|
|
71
|
+
const childResult = Array.isArray(value) ? new Array(value.length) : {};
|
|
72
|
+
out[key] = childResult;
|
|
73
|
+
queue.enqueue({ node: value, result: childResult, path: valuePath });
|
|
37
74
|
}
|
|
38
|
-
cache.set(item, itemPath);
|
|
39
|
-
const childResult = Array.isArray(item) ? new Array(item.length) : {};
|
|
40
|
-
out2[index] = childResult;
|
|
41
|
-
queue.enqueue({ node: item, result: childResult, path: itemPath });
|
|
42
|
-
}
|
|
43
|
-
continue;
|
|
44
75
|
}
|
|
45
|
-
|
|
46
|
-
for (const [key, value] of Object.entries(node)) {
|
|
47
|
-
const valuePath = `${path}/${escapeJsonPointer(key)}`;
|
|
48
|
-
if (typeof value !== "object" || value === null) {
|
|
49
|
-
out[key] = value;
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
const existingPath = cache.get(value);
|
|
53
|
-
if (existingPath !== void 0) {
|
|
54
|
-
out[key] = toRef(existingPath);
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
cache.set(value, valuePath);
|
|
58
|
-
const childResult = Array.isArray(value) ? new Array(value.length) : {};
|
|
59
|
-
out[key] = childResult;
|
|
60
|
-
queue.enqueue({ node: value, result: childResult, path: valuePath });
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return rootResult;
|
|
64
|
-
};
|
|
65
|
-
export {
|
|
66
|
-
toJsonCompatible
|
|
76
|
+
return rootResult;
|
|
67
77
|
};
|
|
68
|
-
//# sourceMappingURL=to-json-compatible.js.map
|
package/dist/queue/queue.js
CHANGED
|
@@ -1,91 +1,110 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Represents a node in a singly linked list structure, used internally by the Queue.
|
|
3
|
+
*
|
|
4
|
+
* Example:
|
|
5
|
+
* const node = new Node<number>(42);
|
|
6
|
+
* console.log(node.data); // 42
|
|
7
|
+
* console.log(node.next); // null
|
|
8
|
+
*/
|
|
9
|
+
export class Node {
|
|
10
|
+
data;
|
|
11
|
+
next;
|
|
12
|
+
constructor(data) {
|
|
13
|
+
this.data = data;
|
|
14
|
+
this.next = null;
|
|
15
|
+
}
|
|
8
16
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
17
|
+
/**
|
|
18
|
+
* A generic queue implementation using a singly linked list.
|
|
19
|
+
*
|
|
20
|
+
* Example usage:
|
|
21
|
+
*
|
|
22
|
+
* const q = new Queue<number>();
|
|
23
|
+
* q.enqueue(1);
|
|
24
|
+
* q.enqueue(2);
|
|
25
|
+
* q.enqueue(3);
|
|
26
|
+
* console.log(q.dequeue()); // 1
|
|
27
|
+
* console.log(q.peek()); // 2
|
|
28
|
+
* console.log(q.getSize()); // 2
|
|
29
|
+
* console.log(q.toString()); // "2 -> 3"
|
|
30
|
+
* console.log(q.isEmpty()); // false
|
|
31
|
+
*/
|
|
32
|
+
export class Queue {
|
|
33
|
+
front;
|
|
34
|
+
rear;
|
|
35
|
+
size;
|
|
36
|
+
constructor() {
|
|
37
|
+
this.front = null;
|
|
38
|
+
this.rear = null;
|
|
39
|
+
this.size = 0;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Adds an element to the end of the queue.
|
|
43
|
+
* @param data - The data to add to the queue.
|
|
44
|
+
*/
|
|
45
|
+
enqueue(data) {
|
|
46
|
+
const newNode = new Node(data);
|
|
47
|
+
if (this.isEmpty() || !this.rear) {
|
|
48
|
+
this.front = newNode;
|
|
49
|
+
this.rear = newNode;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
this.rear.next = newNode;
|
|
53
|
+
this.rear = newNode;
|
|
54
|
+
}
|
|
55
|
+
this.size++;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Removes and returns the front element of the queue.
|
|
59
|
+
* @returns The data from the removed node, or null if the queue is empty.
|
|
60
|
+
*/
|
|
61
|
+
dequeue() {
|
|
62
|
+
if (this.isEmpty() || !this.front) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const removedNode = this.front;
|
|
66
|
+
this.front = this.front.next;
|
|
67
|
+
if (this.front === null) {
|
|
68
|
+
this.rear = null;
|
|
69
|
+
}
|
|
70
|
+
this.size--;
|
|
71
|
+
return removedNode.data;
|
|
30
72
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Returns the front element of the queue without removing it.
|
|
75
|
+
* @returns The front data, or null if the queue is empty.
|
|
76
|
+
*/
|
|
77
|
+
peek() {
|
|
78
|
+
if (this.isEmpty() || !this.front) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
return this.front.data;
|
|
40
82
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Checks whether the queue is empty.
|
|
85
|
+
* @returns True if the queue has no elements, false otherwise.
|
|
86
|
+
*/
|
|
87
|
+
isEmpty() {
|
|
88
|
+
return this.size === 0;
|
|
45
89
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
*/
|
|
53
|
-
peek() {
|
|
54
|
-
if (this.isEmpty() || !this.front) {
|
|
55
|
-
return null;
|
|
90
|
+
/**
|
|
91
|
+
* Returns the number of elements in the queue.
|
|
92
|
+
* @returns The size of the queue.
|
|
93
|
+
*/
|
|
94
|
+
getSize() {
|
|
95
|
+
return this.size;
|
|
56
96
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
*/
|
|
70
|
-
getSize() {
|
|
71
|
-
return this.size;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Returns a string representation of the queue.
|
|
75
|
-
* @returns Elements of the queue separated by ' -> '.
|
|
76
|
-
*/
|
|
77
|
-
toString() {
|
|
78
|
-
let current = this.front;
|
|
79
|
-
const elements = [];
|
|
80
|
-
while (current) {
|
|
81
|
-
elements.push(current.data);
|
|
82
|
-
current = current.next;
|
|
97
|
+
/**
|
|
98
|
+
* Returns a string representation of the queue.
|
|
99
|
+
* @returns Elements of the queue separated by ' -> '.
|
|
100
|
+
*/
|
|
101
|
+
toString() {
|
|
102
|
+
let current = this.front;
|
|
103
|
+
const elements = [];
|
|
104
|
+
while (current) {
|
|
105
|
+
elements.push(current.data);
|
|
106
|
+
current = current.next;
|
|
107
|
+
}
|
|
108
|
+
return elements.join(' -> ');
|
|
83
109
|
}
|
|
84
|
-
return elements.join(" -> ");
|
|
85
|
-
}
|
|
86
110
|
}
|
|
87
|
-
export {
|
|
88
|
-
Node,
|
|
89
|
-
Queue
|
|
90
|
-
};
|
|
91
|
-
//# sourceMappingURL=queue.js.map
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import { REGEX } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
|
|
1
|
+
import { REGEX } from './regex-helpers.js';
|
|
2
|
+
/**
|
|
3
|
+
* Find all strings wrapped in {} or {{}} in value.
|
|
4
|
+
*
|
|
5
|
+
* @param value - The string to find variables in
|
|
6
|
+
* @param includePath - Whether to include path variables {single}
|
|
7
|
+
* @param includeEnv - Whether to include environment variables {{double}}
|
|
8
|
+
*/
|
|
9
|
+
export const findVariables = (value, { includePath = true, includeEnv = true } = {}) => [includePath && REGEX.PATH, includeEnv && REGEX.VARIABLES].flatMap((regex) => regex
|
|
10
|
+
? [...value.matchAll(regex)]
|
|
11
|
+
.map((match) => match[1]?.trim())
|
|
12
|
+
.filter((variable) => variable !== undefined)
|
|
13
|
+
: []);
|
|
@@ -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
|