UNPKG

km-traversal

Version:

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

491 lines 40.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jsonrepair_1 = require("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((0, jsonrepair_1.jsonrepair)(content)) }; } catch (_a) { throw new Error(`Invalid object condition: ${content}`); } } if (content.startsWith('[')) { try { return { type: 'array-cond', conditions: JSON.parse((0, jsonrepair_1.jsonrepair)(content)) }; } catch (_b) { 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 = Object.assign({ 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), }; }, }; }; exports.default = { traverseIn, adapter, defaultConditions: defaultConditions.conditions }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL29iamVjdC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDJDQUF3QztBQW1HeEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILFNBQVMsWUFBWSxDQUFDLE9BQWUsRUFBRSxPQUF5QztJQUM5RSxNQUFNLEtBQUssR0FBa0IsRUFBRSxDQUFDO0lBQ2hDLElBQUksT0FBTyxHQUFHLEVBQUUsQ0FBQztJQUNqQixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDZCxJQUFJLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFFckIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDdkMsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXhCLElBQUksSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsRUFBRTtZQUN4RCxRQUFRLEdBQUcsQ0FBQyxRQUFRLENBQUM7U0FDdEI7UUFFRCxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2IsSUFBSSxJQUFJLEtBQUssR0FBRztnQkFBRSxLQUFLLEVBQUUsQ0FBQztZQUMxQixJQUFJLElBQUksS0FBSyxHQUFHO2dCQUFFLEtBQUssRUFBRSxDQUFDO1lBRTFCLElBQUksSUFBSSxLQUFLLEdBQUcsSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUFFO2dCQUMvQixJQUFJLE9BQU87b0JBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQ3RELE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2IsU0FBUzthQUNWO1NBQ0Y7UUFF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