awesome-json2json
Advanced tools
Comparing version 0.3.1 to 0.4.0
@@ -1,6 +0,13 @@ | ||
export declare type Template<T = any> = IFullTemplate<T> | string | Function; | ||
export interface IFormattingContext { | ||
$root: any; | ||
$item?: any; | ||
} | ||
export interface IFormattingFunction { | ||
(json: any, context?: IFormattingContext): any; | ||
} | ||
export declare type Template<T = any> = IFullTemplate<T> | string | IFormattingFunction; | ||
export interface IFullTemplate<T = any> { | ||
$path?: string; | ||
$formatting?: Function; | ||
$disable?: Function; | ||
$formatting?: IFormattingFunction; | ||
$disable?: IFormattingFunction; | ||
[propName: string]: Template<T>; | ||
@@ -12,4 +19,2 @@ } | ||
export default class Json2json<T> { | ||
private static PATH_SEPARATOR; | ||
private static PATH_ROOT; | ||
private static DISABLED_FIELD; | ||
@@ -22,8 +27,7 @@ static clearEmpty: (json: any) => any; | ||
map(json: any): any; | ||
private mapChild(json, template); | ||
private getFormattedJSON(currentJSON, fullTemplate); | ||
private getFilteredJSON(currentJSON, fullTemplate); | ||
private getJSONByPath(json, path?); | ||
private mapChild(json, template, context); | ||
private getFilteredJSON(currentJSON, fullTemplate, context); | ||
private getJSONByPath(json, path); | ||
private getFullTemplate(template); | ||
private isArrayTemplate(template); | ||
} |
@@ -19,3 +19,3 @@ "use strict"; | ||
this.root = json; | ||
var result = this.mapChild(json, this.template); | ||
var result = this.mapChild(json, this.template, { $root: this.root }); | ||
if (this.options.clearEmpty) { | ||
@@ -26,3 +26,3 @@ return Json2json.clearEmpty(result); | ||
}; | ||
Json2json.prototype.mapChild = function (json, template) { | ||
Json2json.prototype.mapChild = function (json, template, context) { | ||
var fullTemplate = this.getFullTemplate(template); | ||
@@ -32,6 +32,8 @@ var currentJSON = this.getJSONByPath(json, fullTemplate.$path); | ||
if (this.isArrayTemplate(fullTemplate)) { | ||
currentJSON = currentJSON.filter(function (currentJSONItem) { return !(fullTemplate.$disable(currentJSONItem)); }); | ||
currentJSON = currentJSON.filter(function (currentJSONItem) { | ||
return !(fullTemplate.$disable(currentJSONItem, __assign({}, context, { $item: currentJSONItem }))); | ||
}); | ||
} | ||
else { | ||
if (fullTemplate.$disable(currentJSON)) { | ||
if (fullTemplate.$disable(currentJSON, context)) { | ||
return Json2json.DISABLED_FIELD; | ||
@@ -42,16 +44,17 @@ } | ||
if (fullTemplate.$formatting) { | ||
currentJSON = this.getFormattedJSON(currentJSON, fullTemplate); | ||
if (this.isArrayTemplate(fullTemplate)) { | ||
currentJSON = currentJSON.map(function (currentJSONItem) { | ||
return fullTemplate.$formatting(currentJSONItem, __assign({}, context, { $item: currentJSONItem })); | ||
}); | ||
} | ||
else { | ||
currentJSON = fullTemplate.$formatting(currentJSON, context); | ||
} | ||
} | ||
if (Object.keys(fullTemplate).some(function (key) { return !(/^\$/.test(key)); })) { | ||
currentJSON = this.getFilteredJSON(currentJSON, fullTemplate); | ||
currentJSON = this.getFilteredJSON(currentJSON, fullTemplate, context); | ||
} | ||
return currentJSON; | ||
}; | ||
Json2json.prototype.getFormattedJSON = function (currentJSON, fullTemplate) { | ||
if (this.isArrayTemplate(fullTemplate)) { | ||
return currentJSON.map(function (currentJSONItem) { return fullTemplate.$formatting(currentJSONItem); }); | ||
} | ||
return fullTemplate.$formatting(currentJSON); | ||
}; | ||
Json2json.prototype.getFilteredJSON = function (currentJSON, fullTemplate) { | ||
Json2json.prototype.getFilteredJSON = function (currentJSON, fullTemplate, context) { | ||
var _this = this; | ||
@@ -63,3 +66,3 @@ var filteredKeys = Object.keys(fullTemplate).filter(function (key) { return !(/^\$/.test(key)); }); | ||
filteredKeys.forEach(function (key) { | ||
var childResult = _this.mapChild(currentJSONItem, fullTemplate[key]); | ||
var childResult = _this.mapChild(currentJSONItem, fullTemplate[key], __assign({}, context, { $item: currentJSONItem })); | ||
if (childResult !== Json2json.DISABLED_FIELD) { | ||
@@ -74,3 +77,3 @@ result[key] = childResult; | ||
filteredKeys.forEach(function (key) { | ||
var childResult = _this.mapChild(currentJSON, fullTemplate[key]); | ||
var childResult = _this.mapChild(currentJSON, fullTemplate[key], context); | ||
if (childResult !== Json2json.DISABLED_FIELD) { | ||
@@ -86,12 +89,11 @@ result[key] = childResult; | ||
var _this = this; | ||
if (path === void 0) { path = ''; } | ||
if (path === '') | ||
if (path === '' || path.length === 0) | ||
return json; | ||
var splitedPath = path.split(Json2json.PATH_SEPARATOR); | ||
var splitedPath = Array.isArray(path) ? path.slice() : path.split('.'); | ||
if (splitedPath[0] === '$root') { | ||
splitedPath.shift(); | ||
return this.getJSONByPath(this.root, splitedPath.join('.')); | ||
return this.getJSONByPath(this.root, splitedPath); | ||
} | ||
var result = json; | ||
var _loop_1 = function () { | ||
while (splitedPath.length > 0) { | ||
var currentKey = splitedPath.shift(); | ||
@@ -101,6 +103,5 @@ if (/\[\]$/.test(currentKey)) { | ||
result = currentKey === '' ? result : result[currentKey]; | ||
var joinedPath_1 = splitedPath.join('.'); | ||
return { value: result.map(function (jsonItem) { | ||
return _this.getJSONByPath(jsonItem, joinedPath_1); | ||
}) }; | ||
return result.map(function (jsonItem) { | ||
return _this.getJSONByPath(jsonItem, splitedPath); | ||
}); | ||
} | ||
@@ -110,11 +111,6 @@ if (/\?$/.test(currentKey)) { | ||
if (result[currentKey] === undefined) { | ||
return { value: undefined }; | ||
return undefined; | ||
} | ||
} | ||
result = result[currentKey]; | ||
}; | ||
while (splitedPath.length > 0) { | ||
var state_1 = _loop_1(); | ||
if (typeof state_1 === "object") | ||
return state_1.value; | ||
} | ||
@@ -141,4 +137,2 @@ return result; | ||
}; | ||
Json2json.PATH_SEPARATOR = '.'; | ||
Json2json.PATH_ROOT = '$root'; | ||
Json2json.DISABLED_FIELD = '__DISABLED_FIELD__'; | ||
@@ -145,0 +139,0 @@ Json2json.clearEmpty = function (json) { |
{ | ||
"name": "awesome-json2json", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"description": "An awesome json to json mapper", | ||
@@ -5,0 +5,0 @@ "main": "./lib/index.js", |
@@ -27,3 +27,3 @@ # Awesome json2json | ||
Template is the structure of our output json, and the rule of how to map one json data to another. The syntax should look like this: | ||
Template is the structure of output json, and the rule of how to map one json data to another. The syntax should look like this: | ||
@@ -71,2 +71,9 @@ ```js | ||
} | ||
new_foo_array3: { | ||
$path: 'foo_array[]', | ||
new_bar: { | ||
$path: 'bar', | ||
$formatting: (barValue, { $item: fooItem }) => barValue + fooItem.bar | ||
} | ||
} | ||
} | ||
@@ -85,3 +92,8 @@ // Output: | ||
// new_foo_array1: [1, 2, 3], | ||
// new_foo_array2: [1, 2, 3] | ||
// new_foo_array2: [1, 2, 3], | ||
// new_foo_array3: [ | ||
// { new_bar: 2 }, | ||
// { new_bar: 4 }, | ||
// { new_bar: 6 } | ||
// ] | ||
// } | ||
@@ -285,2 +297,45 @@ ``` | ||
### $item and $root inside $formatting | ||
The second parameter of $formatting is the context of current mapping status, including `$item` and `$root`. | ||
```js | ||
json2json({ | ||
foo: [ | ||
{ bar: 1 }, | ||
{ bar: 2 }, | ||
{ bar: 3 } | ||
] | ||
}, { | ||
new_foo: { | ||
$path: 'foo[]', | ||
new_bar1: { | ||
$path: 'bar', | ||
$formatting: (barValue, { $item: fooItem }) => { | ||
return barValue + '_formatted_' + fooItem.bar; | ||
} | ||
}, | ||
new_bar2: (fooItem, { $root }) => { | ||
return fooItem.bar + '_formatted_' + $root.foo.length; | ||
} | ||
} | ||
}); | ||
// { | ||
// new_foo: [ | ||
// { | ||
// new_bar1: '1_formatted_1', | ||
// new_bar2: '1_formatted_3' | ||
// }, | ||
// { | ||
// new_bar1: '2_formatted_2', | ||
// new_bar2: '2_formatted_3' | ||
// }, | ||
// { | ||
// new_bar1: '3_formatted_3', | ||
// new_bar2: '3_formatted_3' | ||
// } | ||
// ] | ||
// } | ||
``` | ||
### Clear all empty data | ||
@@ -287,0 +342,0 @@ |
@@ -1,7 +0,16 @@ | ||
export type Template<T = any> = IFullTemplate<T> | string | Function; | ||
export interface IFormattingContext { | ||
$root: any; | ||
$item?: any; | ||
} | ||
export interface IFormattingFunction { | ||
(json: any, context?: IFormattingContext): any; | ||
} | ||
export type Template<T = any> = IFullTemplate<T> | string | IFormattingFunction; | ||
export interface IFullTemplate<T = any> { | ||
$path?: string; | ||
$formatting?: Function; | ||
$disable?: Function; | ||
$formatting?: IFormattingFunction; | ||
$disable?: IFormattingFunction; | ||
[propName: string]: Template<T>; | ||
@@ -15,4 +24,2 @@ } | ||
export default class Json2json<T> { | ||
private static PATH_SEPARATOR = '.'; | ||
private static PATH_ROOT = '$root'; | ||
private static DISABLED_FIELD = '__DISABLED_FIELD__'; | ||
@@ -54,3 +61,3 @@ public static clearEmpty = (json) => { | ||
this.root = json; | ||
const result = this.mapChild(json, this.template); | ||
const result = this.mapChild(json, this.template, { $root: this.root }); | ||
if (this.options.clearEmpty) { | ||
@@ -61,3 +68,3 @@ return Json2json.clearEmpty(result); | ||
} | ||
private mapChild(json, template: Template) { | ||
private mapChild(json, template: Template, context: IFormattingContext) { | ||
const fullTemplate = this.getFullTemplate(template); | ||
@@ -68,5 +75,10 @@ let currentJSON = this.getJSONByPath(json, fullTemplate.$path); | ||
if (this.isArrayTemplate(fullTemplate)) { | ||
currentJSON = currentJSON.filter((currentJSONItem) => !(fullTemplate.$disable(currentJSONItem))); | ||
currentJSON = currentJSON.filter((currentJSONItem) => { | ||
return !(fullTemplate.$disable(currentJSONItem, { | ||
...context, | ||
$item: currentJSONItem | ||
})); | ||
}); | ||
} else { | ||
if (fullTemplate.$disable(currentJSON)) { | ||
if (fullTemplate.$disable(currentJSON, context)) { | ||
return Json2json.DISABLED_FIELD; | ||
@@ -78,7 +90,16 @@ } | ||
if (fullTemplate.$formatting) { | ||
currentJSON = this.getFormattedJSON(currentJSON, fullTemplate); | ||
if (this.isArrayTemplate(fullTemplate)) { | ||
currentJSON = currentJSON.map((currentJSONItem) => { | ||
return fullTemplate.$formatting(currentJSONItem, { | ||
...context, | ||
$item: currentJSONItem | ||
}); | ||
}); | ||
} else { | ||
currentJSON = fullTemplate.$formatting(currentJSON, context); | ||
} | ||
} | ||
if (Object.keys(fullTemplate).some((key) => !(/^\$/.test(key)))) { | ||
currentJSON = this.getFilteredJSON(currentJSON, fullTemplate); | ||
currentJSON = this.getFilteredJSON(currentJSON, fullTemplate, context); | ||
} | ||
@@ -88,9 +109,3 @@ | ||
} | ||
private getFormattedJSON(currentJSON, fullTemplate: IFullTemplate) { | ||
if (this.isArrayTemplate(fullTemplate)) { | ||
return currentJSON.map((currentJSONItem) => fullTemplate.$formatting(currentJSONItem)); | ||
} | ||
return fullTemplate.$formatting(currentJSON); | ||
} | ||
private getFilteredJSON(currentJSON, fullTemplate: IFullTemplate) { | ||
private getFilteredJSON(currentJSON, fullTemplate: IFullTemplate, context: IFormattingContext) { | ||
const filteredKeys = Object.keys(fullTemplate).filter((key) => !(/^\$/.test(key))); | ||
@@ -102,3 +117,6 @@ | ||
filteredKeys.forEach((key) => { | ||
const childResult = this.mapChild(currentJSONItem, fullTemplate[key]); | ||
const childResult = this.mapChild(currentJSONItem, fullTemplate[key], { | ||
...context, | ||
$item: currentJSONItem | ||
}); | ||
if (childResult !== Json2json.DISABLED_FIELD) { | ||
@@ -114,3 +132,3 @@ result[key] = childResult; | ||
filteredKeys.forEach((key) => { | ||
const childResult = this.mapChild(currentJSON, fullTemplate[key]); | ||
const childResult = this.mapChild(currentJSON, fullTemplate[key], context); | ||
if (childResult !== Json2json.DISABLED_FIELD) { | ||
@@ -124,8 +142,8 @@ result[key] = childResult; | ||
// Syntax reference https://github.com/tc39/proposal-optional-chaining | ||
private getJSONByPath(json, path = '') { | ||
if (path === '') return json; | ||
const splitedPath = path.split(Json2json.PATH_SEPARATOR); | ||
private getJSONByPath(json, path: string | string[]) { | ||
if (path === '' || path.length === 0) return json; | ||
const splitedPath = Array.isArray(path) ? path.slice() : path.split('.'); | ||
if (splitedPath[0] === '$root') { | ||
splitedPath.shift(); | ||
return this.getJSONByPath(this.root, splitedPath.join('.')); | ||
return this.getJSONByPath(this.root, splitedPath); | ||
} | ||
@@ -138,5 +156,4 @@ let result = json; | ||
result = currentKey === '' ? result : result[currentKey]; | ||
const joinedPath = splitedPath.join('.'); | ||
return result.map((jsonItem) => { | ||
return this.getJSONByPath(jsonItem, joinedPath); | ||
return this.getJSONByPath(jsonItem, splitedPath); | ||
}); | ||
@@ -143,0 +160,0 @@ } |
@@ -65,3 +65,10 @@ const assert = require('assert'); | ||
$path: 'foo_array[]', | ||
$formatting: (foo_item) => { return foo_item.bar; } | ||
$formatting: (fooItem) => { return fooItem.bar; } | ||
}, | ||
new_foo_array3: { | ||
$path: 'foo_array[]', | ||
new_bar: { | ||
$path: 'bar', | ||
$formatting: (barValue, { $item: fooItem }) => barValue + fooItem.bar | ||
} | ||
} | ||
@@ -79,3 +86,8 @@ }), { | ||
new_foo_array1: [1, 2, 3], | ||
new_foo_array2: [1, 2, 3] | ||
new_foo_array2: [1, 2, 3], | ||
new_foo_array3: [ | ||
{ new_bar: 2 }, | ||
{ new_bar: 4 }, | ||
{ new_bar: 6 } | ||
] | ||
}); | ||
@@ -196,3 +208,3 @@ }); | ||
}); | ||
it('should match nested $path and $root template value', () => { | ||
it('should match nested $path with $root in template', () => { | ||
assert.deepEqual(json2json(FOO_BAR_BAZ, { | ||
@@ -363,2 +375,146 @@ new_foo: { | ||
}); | ||
describe('context in $formatting', () => { | ||
it('should have $item context in $formatting argument', () => { | ||
assert.deepEqual(json2json(ARRAY_FOO_BAR, { | ||
new_foo: { | ||
$path: 'foo[]', | ||
new_bar: { | ||
$path: 'bar', | ||
$formatting: (barValue, { $item: fooItem }) => { | ||
return barValue + '_formatted_' + fooItem.bar; | ||
} | ||
} | ||
} | ||
}), { | ||
new_foo: [ | ||
{ new_bar: '1_formatted_1' }, | ||
{ new_bar: '2_formatted_2' }, | ||
{ new_bar: '3_formatted_3' } | ||
] | ||
}); | ||
}); | ||
it('should have $root context in $formatting argument', () => { | ||
assert.deepEqual(json2json(ARRAY_FOO_BAR, { | ||
new_foo: { | ||
$path: 'foo[]', | ||
new_bar1: { | ||
$path: 'bar', | ||
$formatting: (barValue, { $item: fooItem }) => { | ||
return barValue + '_formatted_' + fooItem.bar; | ||
} | ||
}, | ||
new_bar2: (fooItem, { $root }) => { | ||
return fooItem.bar + '_formatted_' + $root.foo.length; | ||
} | ||
} | ||
}), { | ||
new_foo: [ | ||
{ | ||
new_bar1: '1_formatted_1', | ||
new_bar2: '1_formatted_3' | ||
}, | ||
{ | ||
new_bar1: '2_formatted_2', | ||
new_bar2: '2_formatted_3' | ||
}, | ||
{ | ||
new_bar1: '3_formatted_3', | ||
new_bar2: '3_formatted_3' | ||
} | ||
] | ||
}); | ||
}); | ||
it('should have currect $item in deep array', () => { | ||
assert.deepEqual(json2json({ | ||
foo: [ | ||
{ | ||
bar: [ | ||
{ baz: 1 }, | ||
{ baz: 2 }, | ||
{ baz: 3 } | ||
] | ||
}, | ||
{ | ||
bar: [ | ||
{ baz: 1 }, | ||
{ baz: 2 }, | ||
{ baz: 3 } | ||
] | ||
}, | ||
{ | ||
bar: [ | ||
{ baz: 1 }, | ||
{ baz: 2 }, | ||
{ baz: 3 } | ||
] | ||
}, | ||
] | ||
}, { | ||
new_foo: { | ||
$path: 'foo[]', | ||
new_bar: { | ||
$path: 'bar[]', | ||
new_baz: { | ||
$path: 'baz', | ||
$formatting: (bazValue, { $item: barItem }) => { | ||
return bazValue + '_formatted_' + barItem.baz; | ||
} | ||
} | ||
}, | ||
} | ||
}), { | ||
new_foo: [ | ||
{ | ||
new_bar: [ | ||
{ new_baz: '1_formatted_1' }, | ||
{ new_baz: '2_formatted_2' }, | ||
{ new_baz: '3_formatted_3' }, | ||
] | ||
}, | ||
{ | ||
new_bar: [ | ||
{ new_baz: '1_formatted_1' }, | ||
{ new_baz: '2_formatted_2' }, | ||
{ new_baz: '3_formatted_3' }, | ||
] | ||
}, | ||
{ | ||
new_bar: [ | ||
{ new_baz: '1_formatted_1' }, | ||
{ new_baz: '2_formatted_2' }, | ||
{ new_baz: '3_formatted_3' }, | ||
] | ||
} | ||
] | ||
}); | ||
}); | ||
it('should have $item and $root context in $disable argument', () => { | ||
assert.deepEqual(json2json(ARRAY_FOO_BAR, { | ||
new_foo: { | ||
$path: 'foo[]', | ||
new_bar1: { | ||
$path: 'bar', | ||
$disable: (barValue, { $item: fooItem }) => { | ||
return fooItem.bar === 2; | ||
} | ||
}, | ||
new_bar2: { | ||
$disable: (fooItem, { $root }) => { | ||
return fooItem.bar === $root.foo.length; | ||
}, | ||
$formatting: (fooItem) => { | ||
return fooItem.bar; | ||
} | ||
} | ||
} | ||
}), { | ||
new_foo: [ | ||
{ new_bar1: 1, new_bar2: 1 }, | ||
{ new_bar2: 2 }, | ||
{ new_bar1: 3 } | ||
] | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -460,2 +616,2 @@ | ||
}); | ||
}) | ||
}); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
50525
1019
368