UNPKG

km-traversal

Version:

This utility provides powerful object traversal capabilities with pattern matching and transformation features.

494 lines 40.8 kB
import { jsonrepair } from 'jsonrepair'; /** * Parses pattern string into executable traversal steps * @param pattern - Traversal pattern string * @returns Array of PatternStep objects * * Pattern Syntax: * - Properties: 'user' * - Single-star: '(*)' , shortcut: '*' * - Double-star: '(**)' , '(*2*)' , shortcut: '*2*' , '**' * - Single-key: '("id")' , (id) * - Multi-key: '("id","name")' , (id,name) * - Object condition: '({"value.startsWith"."a"})' , '({value.startsWith:"a"})' * - Array condition: '([{"value.>":5},{"value.<":10}])' , ([{value.>:5},{value.<:10}]) * * Example: 'users.(*).contacts.(**).email' * Example: `users.(0,"3",'5').contacts.(**).email` * Example: 'users.(*).(contacts).(**).email' * Example: 'users.(*).('contacts',info,"meta").(**).email' * Example: 'users.(*).("contacts").(**).(email,password,phone)' * Example: 'users.(*).("contacts").(**).({key.equalWith:'phone',value:startsWith:"+98"})' * Example: 'users.(*).("contacts").(**).([{key.equalWith:'phone',value:startsWith:"+98"},{key.equalWith:'phone',value:startsWith:"+92"}])' */ function parsePattern(pattern, options) { const steps = []; let current = ''; let depth = 0; let inQuotes = false; for (let i = 0; i < pattern.length; i++) { const char = pattern[i]; if (char === '"' && (i === 0 || pattern[i - 1] !== '\\')) { inQuotes = !inQuotes; } if (!inQuotes) { if (char === '(') depth++; if (char === ')') depth--; if (char === '.' && depth === 0) { if (current) steps.push(createStep(current, options)); current = ''; continue; } } current += char; } if (current) steps.push(createStep(current, options)); return steps; } const isInStringScope = (value) => { const isInSingleQute = value.startsWith('"') && value.endsWith('"'); const isInDoubleQute = value.startsWith("'") && value.endsWith("'"); return { isInDoubleQute, isInSingleQute }; }; /** * Creates a PatternStep from tokenized pattern segment * @param token - Segment of pattern string * @returns Parsed PatternStep */ function createStep(token, options) { if (token.startsWith('(') && token.endsWith(')')) { const content = token.substring(1, token.length - 1).trim(); if (content === '*') return { type: 'single-star' }; const regxOfNumberBeforeDubble = /^(\d*)\*\*$/; const regxOfNumberBetweenDubble = /^\*(\d*)\*$/; const doubleStarMatch = content.match(regxOfNumberBetweenDubble); if (doubleStarMatch) { return doubleStarMatch[1] ? { type: 'double-star', depth: parseInt(doubleStarMatch[1]) } : { type: 'double-star' }; } if (content.startsWith('{')) { try { return { type: 'object-cond', conditions: JSON.parse(jsonrepair(content)) }; } catch { throw new Error(`Invalid object condition: ${content}`); } } if (content.startsWith('[')) { try { return { type: 'array-cond', conditions: JSON.parse(jsonrepair(content)) }; } catch { throw new Error(`Invalid array condition: ${content}`); } } if (!content.includes(',') && !content.startsWith('[') && !content.startsWith('{')) { let stringScope = isInStringScope(content); let repairedContent = content; if (stringScope.isInDoubleQute) { repairedContent = content; } else if (stringScope.isInSingleQute) { repairedContent = content.replace("'", '"'); } else if (stringScope.isInDoubleQute == false && stringScope.isInSingleQute == false) { repairedContent = `"${content}"`; } else { repairedContent = content.replace("'", '"'); } return { type: 'single-key', key: repairedContent.slice(1, -1) }; } if (content.includes(',') && !content.startsWith('[') && !content.startsWith('{') // && // content.split(',').every((part) => part.trim().startsWith('"') && part.trim().endsWith('"')) ) { const repairedContent = content .split(',') .map((part) => { const trimedPart = part.trim(); const stringScope = isInStringScope(trimedPart); if (stringScope.isInDoubleQute) { return part; } else if (stringScope.isInSingleQute) { return part.replace("'", '"'); } else if (stringScope.isInDoubleQute == false && stringScope.isInSingleQute == false) { return `"${part}"`; } else { return part.replace("'", '"'); } }) .join(','); const keys = repairedContent.split(',').map((s) => s.trim().slice(1, -1)); return { type: 'multi-key', keys }; } throw new Error(`Unrecognized pattern token: ${token}`); } if (options.shortcuts.singleStar == true && token.trim() === '*') { const repairedToken = `(${token})`; return createStep(repairedToken, options); } if (options.shortcuts.doubleStar == true && token.trim() === '**') { const repairedToken = `(${token})`; return createStep(repairedToken, options); } if (options.shortcuts.braketScope && token.trim().startsWith('[') && token.trim().endsWith(']')) { const repairedToken = token.trim().replace('[', '(').replace(']', ')'); return createStep(repairedToken, options); } return { type: 'property', name: token }; } /** * Evaluates a condition using injected condition functions * @param cond - Condition string (e.g., 'value.startsWith') * @param condValue - Value to compare against * @param key - Current key * @param value - Current value * @param injectedConditions - Custom condition functions * @returns Boolean evaluation result * * Condition Syntax: * - 'key.conditionName' - Apply to key (in default 'conditionName' === 'key.conditionName') * - '!key.conditionName' - Negate condition Apply to key * - 'value.conditionName' - Apply to value * - '!value.conditionName' - Negate condition Apply to value * - '!conditionName' - Negate condition (in default '!conditionName' === '!key.conditionName') */ function evaluateCondition(cond, condValue, key, value, injectedConditions = []) { const [prefix, conditionName] = cond.split('.'); const negate = prefix.startsWith('!'); const cleanConditionName = conditionName == undefined ? prefix : conditionName; const condition = injectedConditions.find((c) => c.name === cleanConditionName); if (!condition) throw new Error(`Condition not found: ${cleanConditionName}`); const target = prefix.endsWith('value') ? value : key; const result = condition.action(key, value, target, condValue); return negate ? !result : result; } const makeConditions = (conditions) => { return { conditions, names: conditions.map((i) => { return i.name; }), }; }; const defaultConditions = makeConditions([ // String operations { name: 'startsWith', action: (_, __, target, conditionValue) => typeof target === 'string' && target.startsWith(conditionValue), }, { name: 'endsWith', action: (_, __, target, conditionValue) => typeof target === 'string' && target.endsWith(conditionValue), }, { name: 'includes', action: (_, __, target, conditionValue) => typeof target === 'string' && target.includes(conditionValue), }, { name: 'matches', action: (_, __, target, conditionValue) => typeof target === 'string' && new RegExp(conditionValue).test(target), }, // Numeric comparisons { name: 'greaterThan', action: (_, __, target, conditionValue) => typeof target === 'number' && target > conditionValue, }, { name: '>', action: (_, __, target, conditionValue) => typeof target === 'number' && target > conditionValue, }, { name: 'lessThan', action: (_, __, target, conditionValue) => typeof target === 'number' && target < conditionValue, }, { name: '<', action: (_, __, target, conditionValue) => typeof target === 'number' && target < conditionValue, }, { name: 'between', action: (_, __, target, conditionValue) => typeof target === 'number' && target >= conditionValue[0] && target <= conditionValue[1], }, // Equality checks { name: 'equalWith', action: (_, __, target, conditionValue) => target === conditionValue, }, { name: 'notEqual', action: (_, __, target, conditionValue) => target !== conditionValue, }, // Type checking { name: 'isString', action: (_, __, target) => typeof target === 'string', }, { name: 'isNumber', action: (_, __, target) => typeof target === 'number', }, { name: 'isArray', action: (_, __, target) => Array.isArray(target), }, { name: 'isObject', action: (_, __, target) => typeof target === 'object' && !Array.isArray(target) && target !== null, }, // Array operations { name: 'arrayIncludes', action: (_, __, target, conditionValue) => Array.isArray(target) && target.includes(conditionValue), }, { name: 'length', action: (_, __, target, conditionValue) => Array.isArray(target) && target.length === conditionValue, }, ]); /** * Main traversal function for complex data structures * @param data - Input data to traverse * @param options - Configuration options * @param patterns - Array of pattern strings * @param callbacks - Corresponding callbacks for each pattern * * Features: * - Multiple pattern/callback support * - Deep nested traversal * - In-memory data modification * - Conditional filtering * * Usage: * customEach(data, options, patterns, callbacks) */ const traverseIn = (data, options, patterns, callbacks) => { const defaultShortcuts = { singleStar: true, doubleStar: true, braketScope: false, ...options.shortcuts, }; if (patterns.length !== callbacks.length) { throw new Error('Patterns and callbacks must have the same length'); } patterns.forEach((_pattern, index) => { const setCondName = (v) => v; const pattern = typeof _pattern == 'function' ? _pattern({ setCondName }) : typeof _pattern == 'string' ? _pattern : _pattern.join('.'); const steps = parsePattern(pattern, { shortcuts: defaultShortcuts }); const callback = callbacks[index]; let currentNodes = [ { node: data, parent: null, key: null, path: [], }, ]; for (const step of steps) { const nextNodes = []; for (const { node, parent, key, path } of currentNodes) { if (node === null || typeof node !== 'object') continue; switch (step.type) { case 'property': if (typeof node === 'object' && step.name in node) { nextNodes.push({ node: node[step.name], parent: node, key: step.name, path: [...path, step.name], }); } break; case 'single-star': if (Array.isArray(node)) { node.forEach((item, i) => nextNodes.push({ node: item, parent: node, key: i, path: [...path, i], })); } else if (typeof node === 'object') { Object.entries(node).forEach(([k, v]) => nextNodes.push({ node: v, parent: node, key: k, path: [...path, k], })); } break; case 'double-star': const queue = [{ node, parent, key, path, depth: 0 }]; while (queue.length > 0) { const { node: curr, parent: p, key: k, path: pth, depth: d } = queue.shift(); nextNodes.push({ node: curr, parent: p, key: k, path: pth, }); if (step.depth !== undefined && d >= step.depth) continue; if (curr && typeof curr === 'object') { if (Array.isArray(curr)) { curr.forEach((item, i) => queue.push({ node: item, parent: curr, key: i, path: [...pth, i], depth: d + 1, })); } else { Object.entries(curr).forEach(([childKey, childValue]) => queue.push({ node: childValue, parent: curr, key: childKey, path: [...pth, childKey], depth: d + 1, })); } } } break; case 'single-key': if (typeof node === 'object' && step.key in node) { nextNodes.push({ node: node[step.key], parent: node, key: step.key, path: [...path, step.key], }); } break; case 'multi-key': step.keys.forEach((k) => { if (typeof node === 'object' && k in node) { nextNodes.push({ node: node[k], parent: node, key: k, path: [...path, k], }); } }); break; case 'object-cond': if (typeof node === 'object') { Object.entries(node).forEach(([childKey, childValue]) => { const satisfies = Object.entries(step.conditions).every(([cond, condValue]) => evaluateCondition(cond, condValue, childKey, childValue, options.injectedConditions)); if (satisfies) { nextNodes.push({ node: childValue, parent: node, key: childKey, path: [...path, childKey], }); } }); } break; case 'array-cond': if (typeof node === 'object') { Object.entries(node).forEach(([childKey, childValue]) => { const satisfies = step.conditions.some((conditionSet) => Object.entries(conditionSet).every(([cond, condValue]) => evaluateCondition(cond, condValue, childKey, childValue, options.injectedConditions))); if (satisfies) { nextNodes.push({ node: childValue, parent: node, key: childKey, path: [...path, childKey], }); } }); } break; } } currentNodes = nextNodes; } currentNodes.forEach(({ node, parent, key, path }) => { if (key === null) return; // Skip root node callback({ key: key, value: node, objectPath: path, parent, setKey: (newKey) => { if (parent && !Array.isArray(parent)) { parent[newKey] = node; delete parent[key]; } else { throw new Error('Cannot rename array elements or root node'); } }, remove: () => { if (parent && !Array.isArray(parent)) { delete parent[key]; } else { throw new Error('Cannot rename array elements or root node'); } }, removeNears: () => { if (parent && !Array.isArray(parent)) { const nears = Object.keys(parent).filter((item) => { return item !== key; }); nears.forEach((nearKey) => { delete parent[nearKey]; }); } else { throw new Error('Cannot rename array elements or root node'); } }, setValue: (newValue) => { if (parent && key !== null) { if (Array.isArray(parent)) { parent[key] = newValue; } else { parent[key] = newValue; } } else { throw new Error('Cannot set value on root node'); } }, }); }); }); }; const adapter = () => { return { register: (conditions) => { return { traverseIn: (data, patterns, callbacks) => traverseIn(data, { injectedConditions: conditions }, patterns, callbacks), }; }, }; }; export default { traverseIn, adapter, defaultConditions: defaultConditions.conditions }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL29iamVjdC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBbUd4Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBQ0gsU0FBUyxZQUFZLENBQUMsT0FBZSxFQUFFLE9BQXlDO0lBQzlFLE1BQU0sS0FBSyxHQUFrQixFQUFFLENBQUM7SUFDaEMsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDO0lBQ2pCLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNkLElBQUksUUFBUSxHQUFHLEtBQUssQ0FBQztJQUVyQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUN2QyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFeEIsSUFBSSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxFQUFFO1lBQ3hELFFBQVEsR0FBRyxDQUFDLFFBQVEsQ0FBQztTQUN0QjtRQUVELElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDYixJQUFJLElBQUksS0FBSyxHQUFHO2dCQUFFLEtBQUssRUFBRSxDQUFDO1lBQzFCLElBQUksSUFBSSxLQUFLLEdBQUc7Z0JBQUUsS0FBSyxFQUFFLENBQUM7WUFFMUIsSUFBSSxJQUFJLEtBQUssR0FBRyxJQUFJLEtBQUssS0FBSyxDQUFDLEVBQUU7Z0JBQy9CLElBQUksT0FBTztvQkFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDdEQsT0FBTyxHQUFHLEVBQUUsQ0FB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