Security News
pnpm 10.0.0 Blocks Lifecycle Scripts by Default
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
parakeet-mapper
Advanced tools
Simple data conversion library
npm install --save parakeet-mapper
For more options see installation
It's a small collection of utility functions and types that help with mapping (transforming) data.
You can find it useful if:
GraphQL
is not an option 😁npm install --save parakeet-mapper
# or
yarn add parakeet-mapper
ES
import { mapTypes, mapFactory } from 'parakeet-mapper'
CommonJS
const { mapTypes, mapFactory } = require('parakeet-mapper');
Script tag
<!-- Modern es-modules: -->
<script>
import { mapTypes, mapFactory } from 'https://unpkg.com/parakeet-mapper';
</script>
<!-- Or a legacy IIFE script: -->
<script src="https://unpkg.com/parakeet-mapper/dist/parakeet-mapper.iife.js"></script>
<script>
// global variable parakeetMapper
const { mapTypes, mapFactory } = parakeetMapper;
</script>
parakeet-mapper
exposes several helpers to deal with type conversions.
All of them use the TypeMap interface to communicate.
name | overloads | description |
---|---|---|
mapFactory | 3 | Accepts a TypeMap. Returns a function that accepts one input and returns an output converted using rules defined in the TypeMap. |
mapTypes | 3 | Same as mapFactory, but instead of returning a function, accepts input as its first argument and returns an output right away. |
Convertable | 2 | Class mixin. Allows creation of convertable classes. |
object
It is a set of rules that define how the output type is made from the input type.\
The rules are simple:\
true
= the value is assigned from the same key in the input.const input = {
transferred: 'foo',
renamed: 'bar',
converted: '42',
mapped: [1, 1, 2],
omitted: 'won\'t transfer to output'
};
const TypeMap = {
// Transferred straight to the output
transferred: true,
// Renamed from `renamed` into `outputRenamed`
outputRenamed: 'renamed',
// Renamed from `converted` into `convertedNumber`
// and converted from string to number
convertedNumber: { converted: Number },
// Mapped using a function and also renamed.
mappedSum: input => input.mapped.reduce((a, b) => a + b),
// Output object is also accessible in the function as a second parameter
// This allows to reuse operations for already converted values
// (like mappedSum and convertedNumber, in this example)
mappedPlusConverted: (_input, output) => output.mappedSum + output.convertedNumber
};
/* output */ {
transferred: 'foo',
outputRenamed: 'bar',
convertedNumber: 42, // Number('42')
mappedSum: 4,
mappedPlusConverted: 46 // 4 + 42
// notice the absence of `ommited` property
}
new in
v2.1.2
It's not necessary to specify the correct key in the conversion object:
const input = {
number: '42',
};
const TypeMap = {
// Simply converts from string to number using the `Number` function
number: { Number },
};
/* output */ {
number: 42, // Number('42')
// Notice that the property name stayed the same,
// even though we used a `{ Number: Number }` shorthand.
}
It only works if the input has the same property key as the output.
Can also be written using the array (tuple) syntax:
const input = {
number: '42',
};
const TypeMap = {
// Simply converts from string to number using the `Number` function
number: [Number],
};
/* output */ {
number: 42, // Number('42')
// Notice that the property name stayed the same,
// even though we used a `{ Number: Number }` shorthand.
}
function
A factory function that produces a converter from a TypeMap:
import { mapFactory } from 'parakeet-mapper';
const inputToOutput = mapFactory(TypeMap);
const output = inputToOutput(input); /* {
transferred: 'foo',
outputRenamed: 'bar',
convertedNumber: 42, // Number('42')
mappedSum: 4,
mappedPlusConverted: 46 // 4 + 42
// notice the absence of `ommited` property
} */
This function has 3 overloads, all of which are needed for type safety and type inference (TypeScript).
There are basically 3 typed use-cases of using this function (hence 3 overloads):
declare const input: InputType;
const inputConverter = mapFactory<InputType, OutputType>(TypeMap);
// output is OutputType now
declare const input: InputType; // The empty braces are here due to TS issues.
const inputConverter = mapFactory<InputType>()(TypeMap);
declare const input: InputType; // The empty braces are here due to TS issues.
const inputConverter = mapFactory<InputType, OutputType>()(TypeMap);
function
Basically, a mapFactory, called in-place.
First Argument | Second Argument |
---|---|
The input object | Corresponding TypeMap |
import { mapTypes } from 'parakeet-mapper';
const output = mapTypes(input, TypeMap); /* {
transferred: 'foo',
outputRenamed: 'bar',
convertedNumber: 42, // Number('42')
mappedSum: 4,
mappedPlusConverted: 46 // 4 + 42
// notice the absence of `ommited` property
} */
// Same as
// const output = mapFactory(TypeMap)(input);
There are 3. All are semantically the same as the overloads of mapFactory, including the noop call:
/* 1 */ mapTypes<InputType, OutputType>(input, TypeMap);
/* 2 */ mapTypes<InputType>()(input, TypeMap);
/* 3 */ mapTypes<InputType, OutputType>()(input, TypeMap);
function
new inv2.1
A complementary function to mapFactory
that helps to flatten out promises
It produces a converter that returns a flat promise from a converter that returns an object with promises.
In a typical situation, when some convertations are asyncronous, you'd end up with this:
import { mapTypes } from 'parakeet-mapper';
// Imagine that this is requesting something from an API and returns a promise
const requestFromApi = (value) => Promise.resolve(value);
const input = {
a: ['a'],
b: 42,
c: 'c'
};
const getAandBfromAPI = mapFactory({
b: true,
a: { a: requestFromApi },
c: { c: requestFromApi }
});
const output = getAandBfromAPI(input);
// Result:
/* {
a: Promise<['a']>,
b: 42,
c: Promise<'b'>
} */
// Not very comfortable to await every single value after this
Now with wait
:
import { wait } from 'parakeet-mapper';
const waitForAandB = wait(getAandBfromAPI);
const output = getAandBfromAPI(input);
// Result:
/* Promise<{
a: ['a'],
b: 42,
c: 'b'
}> */
// Much more useful now
function
new inv2.1
Internally used in wait
, flattens top-level promises in an object:
import { flattenPromises } from 'parakeet-mapper';
const objWithPromises = {
a: [Promise.resolve('a')],
b: 42,
c: Promise.resolve('b')
};
const flat = flattenPromises(objWithPromises);
// Result
/* Promise<{
a: ['a'],
b: 42,
c: 'b'
}> */
function
new inv2.0
Allows to create classes from converters.
This makes possible adding extra functionality, including reverse convertations.
import { Convertable, mapFactory } from 'parakeet-mapper';
const inputConverter = () => mapFactory(mapTypes);
class Output extends Convertable(inputConverter) {}
const output = new Output(input);
console.log(output); /*
> Output {
transferred: 'foo',
outputRenamed: 'bar',
convertedNumber: 42,
mappedSum: 4,
mappedPlusConverted: 46
}
*/
Accepts a function that returns a converter as its only argument.
Returns a Convertable class with all the required functionality.
Can also infer arguments from its converter factory:
import { Convertable, mapFactory } from 'parakeet-mapper';
const input: InputType = {
foo: 'foo',
bar: 'bar'
}
const inputConverter = (convertFoo?: boolean) => mapFactory<InputType>()({
zoo: convertFoo,
zar: convertFoo ? 'bar' : 'foo'
});
class Output extends Convertable(inputConverter) {}
const outputWithFoo = new Output(input, /* convertFoo? */ true);
console.log(outputWithFoo); /*
> Output {
zoo: 'foo',
zar: 'bar'
}
*/
const outputWithoutFoo = new Output(input, /* convertFoo? */ false);
console.log(outputWithoutFoo); /*
> Output {
zar: 'foo'
}
*/
And accept a reverse converter:
import { Convertable, mapFactory } from 'parakeet-mapper';
const input: InputType = {
foo: 'foo',
bar: 'bar'
}
const inputConverter = (convertFoo?: boolean) => mapFactory<InputType>()({
zoo: convertFoo,
zar: convertFoo ? 'bar' : 'foo'
});
const outputConverter = (convertZoo?: boolean) => mapFactory<OutputType>()({
foo: convertZoo,
bar: convertZoo ? 'zar' : 'zoo'
});
class Output extends Convertable(inputConverter, outputConverter) {}
const output = new Output(input, /* convertFoo? */ true);
console.log(output); /*
> Output {
zoo: 'foo',
zar: 'bar'
}
*/
// Convert back to input type
const newInput = output.toInput(/* convertZoo? */ true);
console.log(newInput); /*
> {
foo: 'foo',
bar: 'bar'
}
*/
constructor
Accepts an input as its first argument and converter factory parameters as other spread arguments.
toInput
Available only if reverse converter was passed into the Convertable.
Accepts a spread of reverse converter arguments
Convertable.createConverter
static
A converter factory, passed to the Convertable.
Convertable.reverseConverter
static
A reverse converter factory, passed to the Convertable.
FAQs
Simple data converter
The npm package parakeet-mapper receives a total of 228 weekly downloads. As such, parakeet-mapper popularity was classified as not popular.
We found that parakeet-mapper demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.