this repo has no description
at main 4.4 kB view raw
1"use strict"; 2Object.defineProperty(exports, "__esModule", { value: true }); 3exports.keyPathContains = exports.keyPathEndsWith = exports.keyPathStartsWith = exports.keyPathsEqual = exports.isKeyPathThis = exports.thisKeyPath = exports.keysOf = void 0; 4const optional_1 = require("../../types/optional"); 5/** 6 * A global cache containing parsed string key paths 7 * with components separated by a dot. 8 */ 9const parsedKeyPaths = {}; 10/** 11 * Extract the individual keys from a key path in order 12 * to traverse into an object to access a specific value. 13 * 14 * @param keyPath - A key path to extract the keys from. 15 * @returns An array containing the keys making up `keyPath`. 16 */ 17function keysOf(keyPath) { 18 // TODO: Normalizing into an array is potentially a bottleneck. 19 // Do we want to do this differently for slower environments? 20 if (Array.isArray(keyPath)) { 21 return keyPath; 22 } 23 else { 24 switch (typeof keyPath) { 25 case "string": { 26 const existingKeyPath = parsedKeyPaths[keyPath]; 27 if ((0, optional_1.isSome)(existingKeyPath)) { 28 return existingKeyPath; 29 } 30 else { 31 const newKeyPath = Object.freeze(keyPath.split(".")); 32 parsedKeyPaths[keyPath] = newKeyPath; 33 return newKeyPath; 34 } 35 } 36 case "number": { 37 return [keyPath]; 38 } 39 case "symbol": { 40 return [keyPath]; 41 } 42 default: { 43 throw new TypeError(`${keyPath.toString()} is not a KeyPath`); 44 } 45 } 46 } 47} 48exports.keysOf = keysOf; 49/** 50 * A key path representing an object itself. 51 */ 52exports.thisKeyPath = Object.freeze([]); 53/** 54 * Determine whether a given key path is the `this` (identity) key path. 55 * @param keyPath - A key path to test. 56 */ 57function isKeyPathThis(keyPath) { 58 return Array.isArray(keyPath) && keyPath.length === 0; 59} 60exports.isKeyPathThis = isKeyPathThis; 61/** 62 * Determines whether two key paths are equivalent taking into account 63 * that the key paths may have different representations. 64 * 65 * @param lhs - A key path to compare. 66 * @param rhs - Another key path to compare. 67 */ 68function keyPathsEqual(lhs, rhs) { 69 // 1. Are the key paths equal through value semantics? 70 if (lhs === rhs) { 71 return true; 72 } 73 const lhsKeys = keysOf(lhs); 74 const rhsKeys = keysOf(rhs); 75 // 2. Do we have the same number of keys in each path? 76 if (lhsKeys.length !== rhsKeys.length) { 77 return false; 78 } 79 // 3. Do any of the keys in our paths differ? 80 for (let index = 0, length = lhsKeys.length; index < length; index += 1) { 81 if (lhsKeys[index] !== rhsKeys[index]) { 82 return false; 83 } 84 } 85 // 4. We have passed all checks and are considered equal. 86 return true; 87} 88exports.keyPathsEqual = keyPathsEqual; 89/** 90 * Determine whether a given key path starts with a specified key. 91 * 92 * @param haystack - A key path to perform a prefix check on. 93 * @param needle - The key to check for. 94 */ 95function keyPathStartsWith(haystack, needle) { 96 if (haystack === needle) { 97 return true; 98 } 99 else { 100 const keys = keysOf(haystack); 101 if (keys.length === 0) { 102 return false; 103 } 104 return keys[0] === needle; 105 } 106} 107exports.keyPathStartsWith = keyPathStartsWith; 108/** 109 * Determine whether a given key path ends with a specified key. 110 * 111 * @param haystack - A key path to perform a suffix check on. 112 * @param needle - The key to check for. 113 */ 114function keyPathEndsWith(haystack, needle) { 115 if (haystack === needle) { 116 return true; 117 } 118 else { 119 const keys = keysOf(haystack); 120 if (keys.length === 0) { 121 return false; 122 } 123 return keys[keys.length - 1] === needle; 124 } 125} 126exports.keyPathEndsWith = keyPathEndsWith; 127/** 128 * Determine whether a given key path contains a specified key. 129 * 130 * @param haystack - A key path to search. 131 * @param needle - The key to search for. 132 */ 133function keyPathContains(haystack, needle) { 134 if (haystack === needle) { 135 return true; 136 } 137 else { 138 const keys = keysOf(haystack); 139 return keys.includes(needle); 140 } 141} 142exports.keyPathContains = keyPathContains; 143//# sourceMappingURL=key-path.js.map