npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jungehaie/extractormap

v3.0.1

Published

Library to extract one JSON data structure from another

Readme

About

ExtractorMap is a utility library to extract the properties of an input object and map those to a given new structure, allowing for transformation of those properties in the process.

Installation

$ npm install --save @jungehaie/extractormap

Usage

An Extractor map ExtractorMap<T, S extends Record<string, any> = any> of a type T has the same keys as T but for every value provides a function extracting the corresponding value of T from a given input of type S.

An ExtractorMap<T, S> is therefore specific to the source of the data as well as to the type of the resulting object T.

From the type defintion you can see you can omit the type of the input S can be omitted, which will result in less typesafety.

ExtractorMap by example

Given a target type T:

{
  "foo": number,
  "bar": string
}

and an input (S)

{
  "qux": 1,
  "quux": "2",
}

An ExractorMap<T, S> could be

{
  "foo": (input: S) => input['qux'],
  "bar": (input: S) => input['quux']
}

Extract

The library provides two ways to extract the target object from the structure:

extract<T, S extends Record<string, any> = any>(map: ExtractorMap<T, S>, input: S): T

Returns an eagerly constructed object of type T that is returnded from extract.

createExtractingProxy<T, S extends Record<string, any> = any>(map: ExtractorMap<T>, input: S): T

Returns a proxy object of type T which allows for accessing the properties of ```T`` via getter. The proxy extracts the values on demand therefore will appear as an empty object when access as whole.

Given the three objects given above one could do the following:

const target: T = extract<T, S>(extractorMap, input);

Hint: extract and createExtractingProxy can also be called in curried form.

In addition there is a version of extract that allows for filtering values that are defined as empty:

extractFilteringEmptys<T, S extends Record<string, any> = any>(map: ExtractorMap<T, S>, input: S): T

Returns an eagerly constructed object of type T that is returnded from extractFilteringEmptys. Any value contained in valuesInterpretedasEmpty will result in the corresponding key not being present in the resulting object.

Helper functions

To simplify the construction of ExtractorMaps the library also provides some helper functions:

jpv<T, S extends Record<string, any> = any, I = T>(jsonPath: string, converterFunction?: (object: I) => T): (input: S => T)

Given a json path and an optional result transformer which defaults to the identity function, returns a function that returns the first (transformed) matching properites value.

jpq<T>(jsonPath: string, converterFunction?: (object: any) => T): (input: object => T)

Given a json path and an optional result transformer which defaults to the identity function, returns a function that returns an array of all (transformed) properties value that match.

jpa<T>(jsonPath: string, converterFunction?: (object: any[]) => T): (input: object => T):

Given a json path and an optional result transformer which defaults to the identity function, returns a function that returns a (transformed) array of all properties value that match.

constant<T>(value: T): (input: unknown => T):

Will return a function returning the given constant disregarding the input object completely.

pickMapGenerator<T, S extends Record<string, any> = any>(keys: ReadonlyArray<keyof T & keyof S>): ExtractorMap<Pick<T, typeof keys[number]>>

Will return an ExtractorMap that extracts the untransformed value of any key contained in the keys array and puts this value under the key by the same name in the output object.

Given those helper functions the ExtractorMap from above could have been written as:

{
  "foo": jpv('qux'),
  "bar": jpv('quux')
}

another ExtractorMap<T, S> could be.

{
  "foo": jpv('quux', x => parseInt(x, 10)),
  "bar": constant('Quux')
}

In addition to the given functions above there are the followinn converter functions

identity<T>(x: T): T:

Returning the input as output. Ususally only necessary as the default value for the convert function in jpv, jpq, jpa, but might be of use to construct your own ExtractorFunction helper.

defaultTo<T>(x: T, forVals?: any[]):T

Returning T if the previous result is a value provided in the forVals. If no forVals are provided only undefind will be used.

Shortcuts and additional functionality

Since using jpv("jsonpath") is by far the most used function there is a shortcut. As long as you don't need a conversion function you can just write the given jsonpath as a string.

So this ExtractorMap

{
  "foo": jpv('qux'),
  "bar": jpv('quux')
}

is equivalent to this ExtractorMap

{
  "foo": 'qux',
  "bar": 'quux'
}

If you provide a definition of your source type all functions where this is possible (e.g. jpv and directly providing a jsonpath) will provide type ahead and type checking for the jsonpath such that only pathes to correct type of your source object are allowed.

Embeded Structures

Since most source and target data strucutes differ in their structure. The above construction would not be very helpful for complex times. For these structures ExtractorMaps can be nested into each other. For a target object like the following:

{
  foo: number,
  bar:  {
    first: string,
    second: number 
  }
}

We don't necessarily need to write the following ExtractorMap like this:

{
  foo: jpv('qux'),
  bar:  jpv('quux')
}

but could use the following nested structure.

{
  foo: jpv('qux'),
  bar:  {
    first: jpv('quux.first'),
    second: jpv('quux.second') 
  }
}

This ist obviously more helpful should the source need to be transformed.