mirror of
https://github.com/rxliuli/apps.apple.com.git
synced 2025-11-09 23:00:32 +00:00
143 lines
4.3 KiB
JavaScript
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
|