@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.
Files changed (123) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/array/add-to-map-array.js +7 -8
  3. package/dist/array/is-defined.js +12 -5
  4. package/dist/array/sort-by-order.js +60 -18
  5. package/dist/consts/content-types.js +13 -14
  6. package/dist/dom/freeze-element.js +56 -42
  7. package/dist/dom/get-selector.d.ts +7 -0
  8. package/dist/dom/get-selector.d.ts.map +1 -0
  9. package/dist/dom/get-selector.js +31 -0
  10. package/dist/dom/scroll-to-id.js +33 -27
  11. package/dist/file/json2xml.js +79 -61
  12. package/dist/formatters/format-bytes.d.ts +7 -0
  13. package/dist/formatters/format-bytes.d.ts.map +1 -0
  14. package/dist/formatters/format-bytes.js +18 -0
  15. package/dist/formatters/format-milliseconds.d.ts +6 -0
  16. package/dist/formatters/format-milliseconds.d.ts.map +1 -0
  17. package/dist/formatters/format-milliseconds.js +10 -0
  18. package/dist/general/create-limiter.js +47 -31
  19. package/dist/general/debounce.js +86 -66
  20. package/dist/general/extract-config-secrets.js +29 -27
  21. package/dist/general/has-modifier.js +9 -8
  22. package/dist/general/is-mac-os.js +23 -21
  23. package/dist/http/can-method-have-body.js +4 -6
  24. package/dist/http/http-info.js +63 -61
  25. package/dist/http/http-methods.js +4 -7
  26. package/dist/http/http-status-codes.js +316 -320
  27. package/dist/http/is-http-method.js +3 -6
  28. package/dist/http/normalize-http-method.js +19 -19
  29. package/dist/json/escape-json-pointer.js +6 -5
  30. package/dist/json/parse-json-pointer-segments.js +11 -6
  31. package/dist/json/pretty-print-json.d.ts +9 -0
  32. package/dist/json/pretty-print-json.d.ts.map +1 -0
  33. package/dist/json/pretty-print-json.js +42 -0
  34. package/dist/json/unescape-json-pointer.js +7 -5
  35. package/dist/markdown/get-markdown-headings.d.ts +11 -0
  36. package/dist/markdown/get-markdown-headings.d.ts.map +1 -0
  37. package/dist/markdown/get-markdown-headings.js +99 -0
  38. package/dist/node/path.js +168 -138
  39. package/dist/object/get-value-at-path.js +17 -11
  40. package/dist/object/is-object.js +24 -10
  41. package/dist/object/local-storage.js +50 -42
  42. package/dist/object/object-entries.js +2 -5
  43. package/dist/object/object-keys.js +5 -5
  44. package/dist/object/object-replace.js +13 -12
  45. package/dist/object/omit-undefined-values.js +18 -18
  46. package/dist/object/prevent-pollution.js +27 -10
  47. package/dist/object/to-json-compatible.js +71 -62
  48. package/dist/queue/queue.js +103 -84
  49. package/dist/regex/find-variables.js +13 -8
  50. package/dist/regex/regex-helpers.js +17 -17
  51. package/dist/regex/replace-variables.js +21 -19
  52. package/dist/string/camel-to-title.js +10 -5
  53. package/dist/string/capitalize.js +5 -5
  54. package/dist/string/create-hash.js +19 -16
  55. package/dist/string/generate-hash.js +153 -127
  56. package/dist/string/iterate-title.js +13 -11
  57. package/dist/string/truncate.js +16 -9
  58. package/dist/testing/console-spies.js +19 -24
  59. package/dist/testing/measure.js +42 -19
  60. package/dist/testing/measure.test-d.js +12 -9
  61. package/dist/testing/sleep.js +5 -5
  62. package/dist/url/ensure-protocol.js +8 -10
  63. package/dist/url/extract-server-from-path.js +53 -28
  64. package/dist/url/is-local-url.js +24 -18
  65. package/dist/url/is-relative-path.js +15 -13
  66. package/dist/url/is-valid-url.js +17 -10
  67. package/dist/url/make-url-absolute.js +39 -28
  68. package/dist/url/merge-urls.js +74 -52
  69. package/dist/url/redirect-to-proxy.js +68 -39
  70. package/package.json +15 -9
  71. package/dist/array/add-to-map-array.js.map +0 -7
  72. package/dist/array/is-defined.js.map +0 -7
  73. package/dist/array/sort-by-order.js.map +0 -7
  74. package/dist/consts/content-types.js.map +0 -7
  75. package/dist/dom/freeze-element.js.map +0 -7
  76. package/dist/dom/scroll-to-id.js.map +0 -7
  77. package/dist/file/json2xml.js.map +0 -7
  78. package/dist/general/create-limiter.js.map +0 -7
  79. package/dist/general/debounce.js.map +0 -7
  80. package/dist/general/extract-config-secrets.js.map +0 -7
  81. package/dist/general/has-modifier.js.map +0 -7
  82. package/dist/general/is-mac-os.js.map +0 -7
  83. package/dist/http/can-method-have-body.js.map +0 -7
  84. package/dist/http/http-info.js.map +0 -7
  85. package/dist/http/http-methods.js.map +0 -7
  86. package/dist/http/http-status-codes.js.map +0 -7
  87. package/dist/http/is-http-method.js.map +0 -7
  88. package/dist/http/normalize-http-method.js.map +0 -7
  89. package/dist/json/escape-json-pointer.js.map +0 -7
  90. package/dist/json/parse-json-pointer-segments.js.map +0 -7
  91. package/dist/json/unescape-json-pointer.js.map +0 -7
  92. package/dist/node/path.js.map +0 -7
  93. package/dist/object/get-value-at-path.js.map +0 -7
  94. package/dist/object/is-object.js.map +0 -7
  95. package/dist/object/local-storage.js.map +0 -7
  96. package/dist/object/object-entries.js.map +0 -7
  97. package/dist/object/object-keys.js.map +0 -7
  98. package/dist/object/object-replace.js.map +0 -7
  99. package/dist/object/omit-undefined-values.js.map +0 -7
  100. package/dist/object/prevent-pollution.js.map +0 -7
  101. package/dist/object/to-json-compatible.js.map +0 -7
  102. package/dist/queue/queue.js.map +0 -7
  103. package/dist/regex/find-variables.js.map +0 -7
  104. package/dist/regex/regex-helpers.js.map +0 -7
  105. package/dist/regex/replace-variables.js.map +0 -7
  106. package/dist/string/camel-to-title.js.map +0 -7
  107. package/dist/string/capitalize.js.map +0 -7
  108. package/dist/string/create-hash.js.map +0 -7
  109. package/dist/string/generate-hash.js.map +0 -7
  110. package/dist/string/iterate-title.js.map +0 -7
  111. package/dist/string/truncate.js.map +0 -7
  112. package/dist/testing/console-spies.js.map +0 -7
  113. package/dist/testing/measure.js.map +0 -7
  114. package/dist/testing/measure.test-d.js.map +0 -7
  115. package/dist/testing/sleep.js.map +0 -7
  116. package/dist/url/ensure-protocol.js.map +0 -7
  117. package/dist/url/extract-server-from-path.js.map +0 -7
  118. package/dist/url/is-local-url.js.map +0 -7
  119. package/dist/url/is-relative-path.js.map +0 -7
  120. package/dist/url/is-valid-url.js.map +0 -7
  121. package/dist/url/make-url-absolute.js.map +0 -7
  122. package/dist/url/merge-urls.js.map +0 -7
  123. package/dist/url/redirect-to-proxy.js.map +0 -7
@@ -1,11 +1,25 @@
1
- const isObject = (value) => {
2
- if (value === null || typeof value !== "object") {
3
- return false;
4
- }
5
- const proto = Object.getPrototypeOf(value);
6
- return proto === Object.prototype || proto === null;
1
+ /**
2
+ * Returns true if the provided value is a record object
3
+ * (i.e. not null, not an array, and has an actual object as the prototype).
4
+ *
5
+ * Differs from the previous isObject in that it returns false for Date,
6
+ * RegExp, Error, Map, Set, WeakMap, WeakSet, Promise, and other non-plain objects.
7
+ *
8
+ * Examples:
9
+ * isObject({}) // true
10
+ * isObject({ a: 1 }) // true
11
+ * isObject([]) // false (Array)
12
+ * isObject(null) // false
13
+ * isObject(123) // false
14
+ * isObject('string') // false
15
+ * isObject(new Error('test')) // false
16
+ * isObject(new Date()) // false
17
+ * isObject(Object.create(null)) // true
18
+ */
19
+ export const isObject = (value) => {
20
+ if (value === null || typeof value !== 'object') {
21
+ return false;
22
+ }
23
+ const proto = Object.getPrototypeOf(value);
24
+ return proto === Object.prototype || proto === null;
7
25
  };
8
- export {
9
- isObject
10
- };
11
- //# sourceMappingURL=is-object.js.map
@@ -1,45 +1,53 @@
1
- const LS_KEYS = {
2
- COLLECTION: "collection",
3
- COOKIE: "cookie",
4
- ENVIRONMENT: "environment",
5
- REQUEST: "request",
6
- REQUEST_EXAMPLE: "requestExample",
7
- SECURITY_SCHEME: "securityScheme",
8
- SERVER: "server",
9
- TAG: "tag",
10
- WORKSPACE: "workspace"
1
+ /**
2
+ * localStorage keys for resources
3
+ * DO NOT CHANGE THESE AS IT WILL BREAK THE MIGRATION
4
+ */
5
+ export const LS_KEYS = {
6
+ COLLECTION: 'collection',
7
+ COOKIE: 'cookie',
8
+ ENVIRONMENT: 'environment',
9
+ REQUEST: 'request',
10
+ REQUEST_EXAMPLE: 'requestExample',
11
+ SECURITY_SCHEME: 'securityScheme',
12
+ SERVER: 'server',
13
+ TAG: 'tag',
14
+ WORKSPACE: 'workspace',
11
15
  };
12
- const REFERENCE_LS_KEYS = {
13
- /**
14
- * Store the selected client as a string in localStorage
15
- */
16
- SELECTED_CLIENT: "scalar-reference-selected-client-v2",
17
- /**
18
- * Store the auth as a string in localStorage
19
- */
20
- AUTH: "scalar-reference-auth"
16
+ /**
17
+ * localStorage keys for all reference resources
18
+ * to ensure we do not have any conflicts
19
+ */
20
+ export const REFERENCE_LS_KEYS = {
21
+ /**
22
+ * Store the selected client as a string in localStorage
23
+ */
24
+ SELECTED_CLIENT: 'scalar-reference-selected-client-v2',
25
+ /**
26
+ * Store the auth as a string in localStorage
27
+ */
28
+ AUTH: 'scalar-reference-auth',
21
29
  };
22
- const CLIENT_LS_KEYS = {
23
- /**
24
- * @deprecated This key is deprecated and will be removed in a future release.
25
- * We are now storing the entire document for the api-client instead.
26
- */
27
- AUTH: "scalar-client-auth",
28
- /**
29
- * @deprecated This key is deprecated and will be removed in a future release.
30
- * We are now storing the entire document for the api-client instead.
31
- */
32
- SELECTED_SECURITY_SCHEMES: "scalar-client-selected-security-schemes"
30
+ /**
31
+ * localStorage keys for all client resources
32
+ * to ensure we do not have any conflicts
33
+ */
34
+ export const CLIENT_LS_KEYS = {
35
+ /**
36
+ * @deprecated This key is deprecated and will be removed in a future release.
37
+ * We are now storing the entire document for the api-client instead.
38
+ */
39
+ AUTH: 'scalar-client-auth',
40
+ /**
41
+ * @deprecated This key is deprecated and will be removed in a future release.
42
+ * We are now storing the entire document for the api-client instead.
43
+ */
44
+ SELECTED_SECURITY_SCHEMES: 'scalar-client-selected-security-schemes',
33
45
  };
34
- const safeLocalStorage = () => typeof window === "undefined" ? {
35
- getItem: () => null,
36
- setItem: () => null,
37
- removeItem: () => null
38
- } : localStorage;
39
- export {
40
- CLIENT_LS_KEYS,
41
- LS_KEYS,
42
- REFERENCE_LS_KEYS,
43
- safeLocalStorage
44
- };
45
- //# sourceMappingURL=local-storage.js.map
46
+ /** SSR safe alias for localStorage */
47
+ export const safeLocalStorage = () => typeof window === 'undefined'
48
+ ? {
49
+ getItem: () => null,
50
+ setItem: () => null,
51
+ removeItem: () => null,
52
+ }
53
+ : localStorage;
@@ -1,5 +1,2 @@
1
- const objectEntries = (obj) => Object.entries(obj);
2
- export {
3
- objectEntries
4
- };
5
- //# sourceMappingURL=object-entries.js.map
1
+ /** Type safe version of Object.entries */
2
+ export const objectEntries = (obj) => Object.entries(obj);
@@ -1,5 +1,5 @@
1
- const objectKeys = (obj) => Object.keys(obj);
2
- export {
3
- objectKeys
4
- };
5
- //# sourceMappingURL=object-keys.js.map
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
- const objectReplace = (target, replacement) => {
2
- Object.keys(target).forEach((key) => {
3
- if (!Object.hasOwn(replacement, key)) {
4
- delete target[key];
5
- }
6
- });
7
- Object.assign(target, replacement);
8
- return target;
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
- const omitUndefinedValues = (data) => {
2
- if (Array.isArray(data)) {
3
- return data.map(
4
- (item) => typeof item === "object" && item !== null ? omitUndefinedValues(item) : item
5
- );
6
- }
7
- return Object.fromEntries(
8
- Object.entries(data).filter(([_, value]) => value !== void 0).map(([key, value]) => {
9
- if (typeof value === "object" && value !== null) {
10
- return [key, omitUndefinedValues(value)];
11
- }
12
- return [key, value];
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
- const PROTOTYPE_POLLUTION_KEYS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
2
- const preventPollution = (key, context) => {
3
- if (PROTOTYPE_POLLUTION_KEYS.has(key)) {
4
- const errorMessage = context ? `Prototype pollution key detected: "${key}" in ${context}` : `Prototype pollution key detected: "${key}"`;
5
- throw new Error(errorMessage);
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 "../json/escape-json-pointer.js";
2
- import { Queue } from "../queue/queue.js";
3
- const toJsonCompatible = (obj, options = {}) => {
4
- const { prefix = "", cache = /* @__PURE__ */ new WeakMap() } = options;
5
- const toRef = (path) => ({ $ref: `#${path ?? ""}` });
6
- if (typeof obj !== "object" || obj === null) {
7
- return obj;
8
- }
9
- const rootPath = prefix;
10
- cache.set(obj, rootPath);
11
- const rootResult = Array.isArray(obj) ? new Array(obj.length) : {};
12
- const queue = new Queue();
13
- queue.enqueue({ node: obj, result: rootResult, path: rootPath });
14
- while (!queue.isEmpty()) {
15
- const frame = queue.dequeue();
16
- if (!frame) {
17
- continue;
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 { node, result, path } = frame;
20
- if (Array.isArray(node)) {
21
- const input = node;
22
- const out2 = result;
23
- for (let index = 0; index < input.length; index++) {
24
- if (!(index in input)) {
25
- continue;
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 item = input[index];
28
- const itemPath = `${path}/${index}`;
29
- if (typeof item !== "object" || item === null) {
30
- out2[index] = item;
31
- continue;
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
- const existingPath = cache.get(item);
34
- if (existingPath !== void 0) {
35
- out2[index] = toRef(existingPath);
36
- continue;
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
- const out = result;
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
@@ -1,91 +1,110 @@
1
- class Node {
2
- data;
3
- next;
4
- constructor(data) {
5
- this.data = data;
6
- this.next = null;
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
- class Queue {
10
- front;
11
- rear;
12
- size;
13
- constructor() {
14
- this.front = null;
15
- this.rear = null;
16
- this.size = 0;
17
- }
18
- /**
19
- * Adds an element to the end of the queue.
20
- * @param data - The data to add to the queue.
21
- */
22
- enqueue(data) {
23
- const newNode = new Node(data);
24
- if (this.isEmpty() || !this.rear) {
25
- this.front = newNode;
26
- this.rear = newNode;
27
- } else {
28
- this.rear.next = newNode;
29
- this.rear = newNode;
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
- this.size++;
32
- }
33
- /**
34
- * Removes and returns the front element of the queue.
35
- * @returns The data from the removed node, or null if the queue is empty.
36
- */
37
- dequeue() {
38
- if (this.isEmpty() || !this.front) {
39
- return null;
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
- const removedNode = this.front;
42
- this.front = this.front.next;
43
- if (this.front === null) {
44
- this.rear = null;
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
- this.size--;
47
- return removedNode.data;
48
- }
49
- /**
50
- * Returns the front element of the queue without removing it.
51
- * @returns The front data, or null if the queue is empty.
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
- return this.front.data;
58
- }
59
- /**
60
- * Checks whether the queue is empty.
61
- * @returns True if the queue has no elements, false otherwise.
62
- */
63
- isEmpty() {
64
- return this.size === 0;
65
- }
66
- /**
67
- * Returns the number of elements in the queue.
68
- * @returns The size of the queue.
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 "./regex-helpers.js";
2
- const findVariables = (value, { includePath = true, includeEnv = true } = {}) => [includePath && REGEX.PATH, includeEnv && REGEX.VARIABLES].flatMap(
3
- (regex) => regex ? [...value.matchAll(regex)].map((match) => match[1]?.trim()).filter((variable) => variable !== void 0) : []
4
- );
5
- export {
6
- findVariables
7
- };
8
- //# sourceMappingURL=find-variables.js.map
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
+ : []);