UNPKG

core-types

Version:

Generic type declarations for e.g. TypeScript, GraphQL and JSON Schema

67 lines (66 loc) 2.23 kB
class StopError extends Error { } export function traverse(node, cb) { function makeNewArg(arg, parentNode, parentProperty, index, required, newNode) { const node = newNode !== undefined ? newNode : index === undefined ? parentNode[parentProperty] : parentNode[parentProperty][index]; const newPath = [ ...arg.path, parentProperty, ...(index === undefined ? [] : [index]), ]; const newValues = { node, path: newPath, parentNode, parentProperty: parentProperty, index, required, }; return Object.assign({}, arg, newValues); } function recurse(arg, cb) { cb(arg); const { node } = arg; if (node.type === 'array') recurse(makeNewArg(arg, node, 'elementType'), cb); else if (node.type === 'tuple') { node.elementTypes.forEach((_, i) => recurse(makeNewArg(arg, node, 'elementTypes', i), cb)); if (typeof node.additionalItems === 'object') recurse(makeNewArg(arg, node, 'additionalItems'), cb); } else if (node.type === 'object') { for (const prop of Object.keys(node.properties)) recurse(makeNewArg(arg, node, 'properties', prop, node.properties[prop].required, node.properties[prop].node), cb); if (typeof node.additionalProperties === 'object') recurse(makeNewArg(arg, node, 'additionalProperties'), cb); } else if (node.type === 'and') node.and.forEach((_, i) => recurse(makeNewArg(arg, node, 'and', i), cb)); else if (node.type === 'or') node.or.forEach((_, i) => recurse(makeNewArg(arg, node, 'or', i), cb)); } const arg = { node, rootNode: node, path: [], }; recurse(arg, cb); } export function some(node, cb) { try { traverse(node, arg => { if (cb(arg)) throw new StopError(); }); } catch (err) { if (err instanceof StopError) return true; throw err; } return false; }