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
text/typescript
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;
// };