Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@bluealba/object-transform

Package Overview
Dependencies
Maintainers
4
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bluealba/object-transform - npm Package Compare versions

Comparing version 1.0.0 to 1.0.1

27

index.js

@@ -5,15 +5,20 @@ "use strict";

const { createSetter } = require("./setter");
const { ExcludeRule, RemapRule } = require("./rules");
const { ExcludeTransformation, RenameTransformation, MapTransformation } = require("./rules");
const TRANSFORMATIONS = {
"rename": RenameTransformation,
"remove": ExcludeTransformation,
"exclude": ExcludeTransformation,
"map": MapTransformation,
}
/**
* Parse rules into an internal format
* Parse transformations into an internal format
*/
const parseRules = rules => rules.map(definition => {
if (definition.type === "remove" || definition.type === "exclude") {
return new ExcludeRule(definition);
const parseTransformation = txs => txs.map(definition => {
const transformationClass = TRANSFORMATIONS[definition.type];
if (!transformationClass) {
throw new Error(`Unrecognized transformation type ${definition.type}`);
}
if (definition.type === "rename" || definition.type === "remap") {
return new RemapRule(definition);
}
throw new Error(`Unrecognized rule type ${definition.type}`);
return new transformationClass(definition);
});

@@ -56,4 +61,4 @@

module.exports = curry((rules, value) => walk(
parseRules(rules),
module.exports = curry((txs, value) => walk(
parseTransformation(txs),
value,

@@ -60,0 +65,0 @@ Array.isArray(value) ? [] : {},

@@ -18,3 +18,3 @@ "use strict";

it("exclusion rule should prevent simple path from be included in result", () => {
it("exclusion transformation should prevent simple path from be included in result", () => {
const result = transform([

@@ -34,3 +34,3 @@ { path: "age", type: "remove" }

it("exclusion rule can remove a complex object", () => {
it("exclusion transformation can remove a complex object", () => {
const result = transform([

@@ -47,3 +47,3 @@ { path: "address", type: "remove" },

it("exclusion rule can remove a nested property", () => {
it("exclusion transformation can remove a nested property", () => {
const result = transform([

@@ -63,3 +63,3 @@ { path: "address.city", type: "remove" },

it("several exclusion rules should work independently", () => {
it("several exclusion transformations should work independently", () => {
const result = transform([

@@ -76,3 +76,3 @@ { path: "age", type: "remove" },

it("non-matching exclusion rule should not change anything", () => {
it("non-matching exclusion transformation should not change anything", () => {
const result = transform([

@@ -97,3 +97,3 @@ { path: "somethingelse", type: "remove" },

it("rename rule should rename a simple property", () => {
it("rename transformation should rename a simple property", () => {
const result = transform([

@@ -114,3 +114,3 @@ { path: "lastName", type: "rename", toPath: "surname" }

it("rename rule can rename a complex object", () => {
it("rename transformation can rename a complex object", () => {
const result = transform([

@@ -131,3 +131,3 @@ { path: "address", type: "rename", toPath: "location" }

it("rename rule can rename a nested property", () => {
it("rename transformation can rename a nested property", () => {
const result = transform([

@@ -148,3 +148,3 @@ { path: "address.line1", type: "rename", toPath: "address.line" }

it("multiple rename rules are applied in order", () => {
it("multiple rename transformations are applied in order", () => {
const result = transform([

@@ -166,3 +166,3 @@ { path: "address", type: "rename", toPath: "location" },

it("rename rule can relocate a property into a newer object", () => {
it("rename transformation can relocate a property into a newer object", () => {
const result = transform([

@@ -185,3 +185,3 @@ { path: "age", type: "rename", toPath: "data.age" },

it("rename rule can relocate a property into an existent object", () => {
it("rename transformation can relocate a property into an existent object", () => {
const result = transform([

@@ -202,3 +202,3 @@ { path: "age", type: "rename", toPath: "address.age" },

it("rename rule can work with wildcards", () => {
it("rename transformation can work with wildcards", () => {
const result = transform([

@@ -220,3 +220,39 @@ { path: "*.line1", type: "rename", toPath: "$1.line" },

it("rules can be used to transform items inside an array", () => {
describe("map", () => {
it("map transformation should map the value", () => {
const result = transform([
{ path: "firstName", type: "map", fn: value => value + " J." }
])(bart);
expect(result).toEqual({
firstName: "Bart J.",
lastName: "Simpson",
age: 10,
address: {
line1: "742 Evergreen Terrace",
city: "Springfield"
}
})
});
it("map and rename transformation can be used together", () => {
const result = transform([
{ path: "firstName", type: "rename", toPath: "name" },
{ path: "name", type: "map", fn: value => value + " J." }
])(bart);
expect(result).toEqual({
name: "Bart J.",
lastName: "Simpson",
age: 10,
address: {
line1: "742 Evergreen Terrace",
city: "Springfield"
}
})
});
});
it("transformations can be used to transform items inside an array", () => {
const result = transform([

@@ -223,0 +259,0 @@ { path: "[].address", type: "remove" },

{
"name": "@bluealba/object-transform",
"version": "1.0.0",
"description": "A configurable object tranformer",
"version": "1.0.1",
"description": "A declarative library for transforming objects",
"main": "index.js",

@@ -11,3 +11,3 @@ "author": "Claudio Fernandez <claudio.fernandez@bluealba.com>",

"lint": "eslint '.'",
"coverage": "jest --coverage && cat ./tests/coverage/lcov.info | coveralls"
"coverage": "jest --coverage && cat ./coverage/lcov.info | coveralls"
},

@@ -23,4 +23,4 @@ "devDependencies": {

"jest": {
"collectCoverage": true
},
"collectCoverage": true
},
"repository": {

@@ -27,0 +27,0 @@ "closure": "git",

# @bluealba/object-transform
[![Build Status](https://travis-ci.org/bluealba/object-transform.svg?branch=master)](https://travis-ci.org/bluealba/object-transform)
[![npm](https://img.shields.io/npm/v/bluealba/object-transform.svg)](https://npmjs.org/package/bluealba/object-transform.svg)
[![npm](https://img.shields.io/npm/dt/bluealba/object-transform.svg)](https://npmjs.org/package/bluealba/object-transform.svg)
[![npm](https://img.shields.io/npm/v/@bluealba/object-transform.svg)](https://npmjs.org/package/@bluealba/object-transform.svg)
[![npm](https://img.shields.io/npm/dt/@bluealba/object-transform.svg)](https://npmjs.org/package/@bluealba/object-transform.svg)
![David](https://img.shields.io/david/bluealba/object-transform.svg)
[![Coverage Status](https://coveralls.io/repos/github/bluealba/object-transform/badge.svg?branch=master)](https://coveralls.io/github/bluealba/object-transform?branch=master)
## Overview

@@ -48,4 +49,4 @@ The main purpose of this module is to perform a series of declarative transformations over an input object returning a modified output object (this library do not have side effect over its input).

const output = transform([
{ type: "remap", path: "collection", toPath: "books" },
{ type: "remap", path: "books.[].code", toPath: "books.$1.codes.isbn" },
{ type: "rename", path: "collection", toPath: "books" },
{ type: "rename", path: "books.[].code", toPath: "books.$1.codes.isbn" },
{ type: "exclude", path: "books.[].rating" },

@@ -94,6 +95,6 @@ ], input);

Even though we plan to expand this currently only two types of transformations are supported
Even though we plan to expand this currently only three basic types of transformations are supported
### Exclude transformation
Formerly known as `remove`. The simplest transformation. It is configured only with a `path`. Any given node whose path matches this rule will be excluded from the final output. Its children won't be included as well, unless a `remap` transformation alters that behavior.
Formerly known as `remove`. The simplest transformation. It is configured only with a `path`. Any given node whose path matches this rule will be excluded from the final output. Its children won't be included as well, unless a `rename` transformation alters that behavior.

@@ -105,4 +106,4 @@ Example:

### Remap transformation
Formerly known as `rename`. The remap takes a `path` and new path (`toPath`). It will simple "move" any node that matches to the newer destination.
### Rename transformation
The rename takes a `path` and new path (`toPath`). It will simple "move" any node that matches to the newer destination.

@@ -117,2 +118,16 @@ Captured group placeholders (`$1`, `$2`...) can be used to match the values of the `path` wildcards (`[]` and `*`)

Example:
```
{ type: "rename", path: "books.[].author", toPath: "books.$1.authors" }
```
### Map transformation
The map doesn't affect the matched node path but its value. It's configured with a transformation function `fn` that
receives both the value and the full path and returns the new value.
```
{ type: "map", path: "books.[].author", fn: (value, path) => value.toUppercase() }
```
# Known limitations

@@ -119,0 +134,0 @@ Currently we don't support cicles. We are aiming this to perform transformation in JSON-like tree structures. We might

@@ -19,3 +19,3 @@ "use strict";

/**
* A rule determines how a value associated to a certain path of the
* A transformation determines how a value associated to a certain path of the
* `original object` will be treated. It does that by replacing the

@@ -25,6 +25,6 @@ * original setter object that will be used to set the value into

*
* Every rules is associated to a matcher which determines if a given
* path need to be intercepted by this rule or not.
* Every transformation is associated to a matcher which determines if a given
* path need to be intercepted by this transformation or not.
*/
class Rule {
class Transformation {
constructor({ path }) {

@@ -44,3 +44,3 @@ this.matcher = expressionLens(path);

*/
class ExcludeRule extends Rule {
class ExcludeTransformation extends Transformation {
apply(setter) {

@@ -51,6 +51,17 @@ return createDummySetter(setter.propertyPath);

class MapTransformation extends Transformation {
constructor({ path, fn }) {
super({ path });
this.fn = fn;
}
apply(setter) {
return setter.intercept(this.fn)
}
}
/**
* If applies replaces the setter for a dummy setter
*/
class RemapRule extends Rule {
class RenameTransformation extends Transformation {
constructor({ path, toPath }) {

@@ -70,4 +81,5 @@ super({ path });

module.exports = {
ExcludeRule,
RemapRule
ExcludeTransformation,
RenameTransformation,
MapTransformation
}
"use strict";
const { set, lensPath, mergeRight, over } = require("ramda");
const { set, lensPath, mergeRight, over, identity } = require("ramda");
class Setter {
constructor(propertyPath) {
constructor(propertyPath, interceptFn) {
this.propertyPath = propertyPath;
this.interceptFn = interceptFn || identity;
}
set(value, target) {
return set(lensPath(this.propertyPath), value, target);
const interceptedValue = this.interceptFn(value);
return set(lensPath(this.propertyPath), interceptedValue, target);
}
merge(value, target) {
return over(lensPath(this.propertyPath), mergeRight(value), target);
const interceptedValue = this.interceptFn(value);
return over(lensPath(this.propertyPath), mergeRight(interceptedValue), target);
}

@@ -21,2 +24,6 @@

}
intercept(interceptFn) {
return new this.constructor(this.propertyPath, interceptFn);
}
}

@@ -23,0 +30,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc