Files
apps.apple.com/node_modules/@jet/environment/json/reader/key-path.js
2025-11-04 05:03:50 +08:00

143 lines
4.3 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.keyPathContains = exports.keyPathEndsWith = exports.keyPathStartsWith = exports.keyPathsEqual = exports.isKeyPathThis = exports.thisKeyPath = exports.keysOf = void 0;
const optional_1 = require("../../types/optional");
/**
* A global cache containing parsed string key paths
* with components separated by a dot.
*/
const parsedKeyPaths = {};
/**
* Extract the individual keys from a key path in order
* to traverse into an object to access a specific value.
*
* @param keyPath - A key path to extract the keys from.
* @returns An array containing the keys making up `keyPath`.
*/
function keysOf(keyPath) {
// TODO: Normalizing into an array is potentially a bottleneck.
// Do we want to do this differently for slower environments?
if (Array.isArray(keyPath)) {
return keyPath;
}
else {
switch (typeof keyPath) {
case "string": {
const existingKeyPath = parsedKeyPaths[keyPath];
if ((0, optional_1.isSome)(existingKeyPath)) {
return existingKeyPath;
}
else {
const newKeyPath = Object.freeze(keyPath.split("."));
parsedKeyPaths[keyPath] = newKeyPath;
return newKeyPath;
}
}
case "number": {
return [keyPath];
}
case "symbol": {
return [keyPath];
}
default: {
throw new TypeError(`${keyPath.toString()} is not a KeyPath`);
}
}
}
}
exports.keysOf = keysOf;
/**
* A key path representing an object itself.
*/
exports.thisKeyPath = Object.freeze([]);
/**
* Determine whether a given key path is the `this` (identity) key path.
* @param keyPath - A key path to test.
*/
function isKeyPathThis(keyPath) {
return Array.isArray(keyPath) && keyPath.length === 0;
}
exports.isKeyPathThis = isKeyPathThis;
/**
* Determines whether two key paths are equivalent taking into account
* that the key paths may have different representations.
*
* @param lhs - A key path to compare.
* @param rhs - Another key path to compare.
*/
function keyPathsEqual(lhs, rhs) {
// 1. Are the key paths equal through value semantics?
if (lhs === rhs) {
return true;
}
const lhsKeys = keysOf(lhs);
const rhsKeys = keysOf(rhs);
// 2. Do we have the same number of keys in each path?
if (lhsKeys.length !== rhsKeys.length) {
return false;
}
// 3. Do any of the keys in our paths differ?
for (let index = 0, length = lhsKeys.length; index < length; index += 1) {
if (lhsKeys[index] !== rhsKeys[index]) {
return false;
}
}
// 4. We have passed all checks and are considered equal.
return true;
}
exports.keyPathsEqual = keyPathsEqual;
/**
* Determine whether a given key path starts with a specified key.
*
* @param haystack - A key path to perform a prefix check on.
* @param needle - The key to check for.
*/
function keyPathStartsWith(haystack, needle) {
if (haystack === needle) {
return true;
}
else {
const keys = keysOf(haystack);
if (keys.length === 0) {
return false;
}
return keys[0] === needle;
}
}
exports.keyPathStartsWith = keyPathStartsWith;
/**
* Determine whether a given key path ends with a specified key.
*
* @param haystack - A key path to perform a suffix check on.
* @param needle - The key to check for.
*/
function keyPathEndsWith(haystack, needle) {
if (haystack === needle) {
return true;
}
else {
const keys = keysOf(haystack);
if (keys.length === 0) {
return false;
}
return keys[keys.length - 1] === needle;
}
}
exports.keyPathEndsWith = keyPathEndsWith;
/**
* Determine whether a given key path contains a specified key.
*
* @param haystack - A key path to search.
* @param needle - The key to search for.
*/
function keyPathContains(haystack, needle) {
if (haystack === needle) {
return true;
}
else {
const keys = keysOf(haystack);
return keys.includes(needle);
}
}
exports.keyPathContains = keyPathContains;
//# sourceMappingURL=key-path.js.map