UNPKG

eslint-plugin-logical-properties

Version:
81 lines (80 loc) 3.29 kB
import { isValidProperty } from './isValidProperty.js'; import { isWildcard, pathToSegments, segmentsToPath, } from './propertyTraverse.utils.js'; import { getValidPropertyName } from './getValidPropertyName.js'; export const propertyTraverse = (node, path) => { const [current, ...nextSegments] = pathToSegments(path); let currentSelector = current; // Account for no further segments if (!current && node.type === 'ObjectExpression') { return [node]; } // Account for square brackets (string or number selector) const squareBracketsMatch = current.match(/\[([^\]]+)]/); if (squareBracketsMatch) { const [, currentMatch] = squareBracketsMatch; if (node.type === 'ArrayExpression') { if (/^\d+$/.test(currentMatch)) { const index = Number.parseInt(currentMatch, 10); const nextProperty = node.elements[index]; if (nextProperty && nextProperty.type === 'ObjectExpression') { return propertyTraverse(nextProperty, segmentsToPath(nextSegments)); } } // Wildcard selector on array elements if (isWildcard(currentMatch)) { const elements = []; for (const element of node.elements) { if (element?.type === 'ObjectExpression') { elements.push(element); } } return elements.flatMap((element) => propertyTraverse(element, segmentsToPath(nextSegments))); } } currentSelector = currentMatch; } // Wildcard selector if (isWildcard(currentSelector)) { if (node.type === 'ObjectExpression') { const elements = []; for (const property of node.properties) { if (isValidProperty(property) && property.value.type === 'ObjectExpression') { elements.push(property.value); } } return elements.flatMap((element) => propertyTraverse(element, segmentsToPath(nextSegments))); } if (node.type === 'ArrayExpression') { const elements = []; for (const element of node.elements) { if (element?.type === 'ObjectExpression') { elements.push(element); } } return elements.flatMap((element) => propertyTraverse(element, segmentsToPath(nextSegments))); } } if (node.type !== 'ObjectExpression') { return []; } // Direct selector const nextProperty = node.properties.find((property) => { if (isValidProperty(property)) { const propertyName = getValidPropertyName(property); return propertyName === currentSelector; } return false; }); if (nextProperty && isValidProperty(nextProperty) && nextProperty.value.type === 'ObjectExpression') { return propertyTraverse(nextProperty.value, segmentsToPath(nextSegments)); } return []; }; export const propertyTraverseSet = (node, paths) => { const properties = paths .flatMap((path) => propertyTraverse(node, path)) .filter(Boolean); return properties; };