UNPKG

jsonpath-mapper

Version:

A json to json transformation utility with a few nice features to use when translating for example API responses into a domain object for use in your domain-driven JavaScript applications. Can be used in React applications with the 'useMapper' hook.

101 lines (85 loc) 2.99 kB
import { JSONPath } from 'jsonpath-plus'; // import jsonpath from 'simple-jsonpath'; import { DefaultFunction, DisableFunction, MapperFunctions, MappingElement, Path, WireFunction, } from './models/Template.js'; export { default as fromEntries } from 'fromentries'; export const jpath = <S, T>(query: string, json: S): T | T[] => { const result = JSONPath({ path: `$${query.startsWith('.') ? '' : '.'}${query}`, json: json as any, }); // const result = jsonpath.query( // json, // `$${query.startsWith('.') ? '' : '.'}${query}` // ); if ( result.length > 1 || (query.match(/\[.*?\]/) && !query.match(/\[[0-9]\]/)) ) return result; return result[0]; }; export const isArray = (val: any): val is any[] => val && Array.isArray(val); export const isMultiplePaths = (val: Path): val is string[] => Array.isArray(val); export const isWireFunction = <S>( val: | MappingElement<S> | WireFunction<S> | DisableFunction<S> | DefaultFunction<S> ): val is WireFunction<S> => typeof val === 'function'; export const isNull = (val: any): val is null => val === null; export const isUndefined = (val: any): val is undefined => typeof val === 'undefined'; export const isNullOrUndefined = (val: any): val is null | undefined => { if (isUndefined(val)) return true; if (isNull(val)) return true; return false; }; export const isNumber = (val: any): val is number => typeof val === 'number'; export const isMapperFunctions = <S>( val: MappingElement<S> ): val is MapperFunctions<S> => typeof val === 'object' && '$path' in val; export const isObject = <S>(val: MappingElement<S>): val is MappingElement<S> => typeof val === 'object'; export const isString = <S>(val: MappingElement<S>): val is string => typeof val === 'string'; export const isStringArray = <S>(val: MappingElement<S>): val is string[] => Array.isArray(val) && val.every((it) => typeof it === 'string'); export const tryMultiple = <S>( json: S, arr: MappingElement<S>[], $root: S, findMultiple: (json: S, arr: MappingElement<S>[], $root: S) => any[] ) => { const result = findMultiple(json, arr, $root).filter(r => isNumber(r) || r); if (arr.every(i => (typeof i === "string"))) return result.length > 0 ? result[0] : null; return result; }; // const findMultiple = <S>( // json: S, // arr: MappingElement<S>[], // $root: S // ): any[] => { // const results = arr.map(inner => { // // evaluate any value supplied as string // if (isString(inner)) { // return jpath(inner, json); // } // // if typeof func // if (isWireFunction(inner)) return inner(json, $root); // if (isMapperFunctions(inner)) { // return handleMappingFunctions([, inner], json, $root); // } // if (typeof inner === 'object') return mapObject(json, inner, $root); // }); // return results; // };