Socket
Socket
Sign inDemoInstall

flat

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

flat - npm Package Compare versions

Comparing version 1.1.0 to 1.2.0

128

index.js

@@ -1,73 +0,87 @@

var flat = module.exports = {}
var flat = module.exports = {
flatten: flatten
, unflatten: unflatten
}
var flatten = flat.flatten = function (target, opts) {
var output = {}
, opts = opts || {}
, delimiter = opts.delimiter || '.'
function flatten(target, opts) {
opts = opts || {}
function getkey(key, prev) {
return prev ? prev + delimiter + key : key
};
var delimiter = opts.delimiter || '.'
var output = {}
function step(object, prev) {
Object.keys(object).forEach(function(key) {
var isarray = opts.safe && Array.isArray(object[key])
, type = Object.prototype.toString.call(object[key])
, isobject = (type === "[object Object]" || type === "[object Array]")
function step(object, prev) {
Object.keys(object).forEach(function(key) {
var value = object[key]
var isarray = opts.safe && Array.isArray(value)
var type = Object.prototype.toString.call(value)
var isobject = (
type === "[object Object]" ||
type === "[object Array]"
)
if (!isarray && isobject) {
return step(object[key]
, getkey(key, prev)
)
}
var newKey = prev
? prev + delimiter + key
: key
output[getkey(key, prev)] = object[key]
});
};
if (!isarray && isobject) {
return step(value, newKey)
}
step(target)
output[newKey] = value
})
}
return output
};
step(target)
var unflatten = flat.unflatten = function (target, opts) {
var opts = opts || {}
, delimiter = opts.delimiter || '.'
, result = {}
return output
}
if (Object.prototype.toString.call(target) !== '[object Object]') {
return target
}
function unflatten(target, opts) {
opts = opts || {}
function getkey(key) {
var parsedKey = parseInt(key)
return (isNaN(parsedKey) ? key : parsedKey)
};
var delimiter = opts.delimiter || '.'
var result = {}
Object.keys(target).forEach(function(key) {
var split = key.split(delimiter)
, firstNibble
, secondNibble
, recipient = result
if (Object.prototype.toString.call(target) !== '[object Object]') {
return target
}
firstNibble = getkey(split.shift())
secondNibble = getkey(split[0])
// safely ensure that the key is
// an integer.
function getkey(key) {
var parsedKey = Number(key)
while (secondNibble !== undefined) {
if (recipient[firstNibble] === undefined) {
recipient[firstNibble] = ((typeof secondNibble === 'number') && !opts.object ? [] : {})
}
return (
isNaN(parsedKey) ||
key.indexOf('.') !== -1
) ? key
: parsedKey
}
recipient = recipient[firstNibble]
if (split.length > 0) {
firstNibble = getkey(split.shift())
secondNibble = getkey(split[0])
}
}
Object.keys(target).forEach(function(key) {
var split = key.split(delimiter)
var key1 = getkey(split.shift())
var key2 = getkey(split[0])
var recipient = result
// unflatten again for 'messy objects'
recipient[firstNibble] = unflatten(target[key])
});
while (key2 !== undefined) {
if (recipient[key1] === undefined) {
recipient[key1] = (
typeof key2 === 'number' &&
!opts.object ? [] : {}
)
}
return result
};
recipient = recipient[key1]
if (split.length > 0) {
key1 = getkey(split.shift())
key2 = getkey(split[0])
}
}
// unflatten again for 'messy objects'
recipient[key1] = unflatten(target[key])
})
return result
}
{
"name": "flat",
"version": "1.1.0",
"version": "1.2.0",
"main": "index.js",

@@ -5,0 +5,0 @@ "scripts": {

@@ -6,283 +6,310 @@ var assert = require('assert')

suite('Flatten Primitives', function(){
test('String', function(){
assert.deepEqual(flatten({hello:{world: "good morning"}}),{'hello.world':'good morning'})
var primitives = {
String: 'good morning'
, Number: 1234.99
, Boolean: true
, Date: new Date
, null: null
, undefined: undefined
}
suite('Flatten Primitives', function() {
Object.keys(primitives).forEach(function(key) {
var value = primitives[key]
test(key, function() {
assert.deepEqual(flatten({
hello: {
world: value
}
}), {
'hello.world': value
})
})
test('Number', function(){
assert.deepEqual(flatten({hello:{world: 1234.99}}),{'hello.world': 1234.99})
})
test('Boolean', function(){
assert.deepEqual(flatten({hello:{world: true}}),{'hello.world': true})
assert.deepEqual(flatten({hello:{world: false}}),{'hello.world': false})
})
test('Date', function(){
var d = new Date()
assert.deepEqual(flatten({hello:{world: d}}),{'hello.world': d})
})
test('Null', function(){
assert.deepEqual(flatten({hello:{world: null}}),{'hello.world': null})
})
test('Undefined', function(){
assert.deepEqual(flatten({hello:{world: undefined}}),{'hello.world': undefined})
})
})
})
suite('Unflatten Primitives', function(){
test('String', function(){
assert.deepEqual(unflatten({'hello.world':'good morning'}),{hello:{world: "good morning"}})
suite('Unflatten Primitives', function() {
Object.keys(primitives).forEach(function(key) {
var value = primitives[key]
test(key, function() {
assert.deepEqual(unflatten({
'hello.world': value
}), {
hello: {
world: value
}
})
})
test('Number', function(){
assert.deepEqual(unflatten({'hello.world': 1234.99}),{hello:{world: 1234.99}})
})
test('Boolean', function(){
assert.deepEqual(unflatten({'hello.world': true}),{hello:{world: true}})
assert.deepEqual(unflatten({'hello.world': false}),{hello:{world: false}})
})
test('Date', function(){
var d = new Date()
assert.deepEqual(unflatten({'hello.world': d}),{hello:{world: d}})
})
test('Null', function(){
assert.deepEqual(unflatten({'hello.world': null}),{hello:{world: null}})
})
test('Undefined', function(){
assert.deepEqual(unflatten({'hello.world': undefined}),{hello:{world: undefined}})
})
})
})
suite('Flatten', function() {
test('Nested once', function() {
assert.deepEqual(flatten({
hello: {
world: 'good morning'
}
}), {
'hello.world': 'good morning'
})
test('Nested once', function() {
assert.deepEqual(flatten({
hello: {
world: 'good morning'
}
}), {
'hello.world': 'good morning'
})
test('Nested twice', function() {
assert.deepEqual(flatten({
hello: {
world: {
again: 'good morning'
}
}
}), {
'hello.world.again': 'good morning'
})
})
test('Nested twice', function() {
assert.deepEqual(flatten({
hello: {
world: {
again: 'good morning'
}
}
}), {
'hello.world.again': 'good morning'
})
test('Multiple Keys', function() {
assert.deepEqual(flatten({
hello: {
lorem: {
ipsum: 'again',
dolor: 'sit'
}
},
world: {
lorem: {
ipsum: 'again',
dolor: 'sit'
}
}
}), {
'hello.lorem.ipsum': 'again',
'hello.lorem.dolor': 'sit',
'world.lorem.ipsum': 'again',
'world.lorem.dolor': 'sit'
})
})
test('Multiple Keys', function() {
assert.deepEqual(flatten({
hello: {
lorem: {
ipsum: 'again',
dolor: 'sit'
}
},
world: {
lorem: {
ipsum: 'again',
dolor: 'sit'
}
}
}), {
'hello.lorem.ipsum': 'again',
'hello.lorem.dolor': 'sit',
'world.lorem.ipsum': 'again',
'world.lorem.dolor': 'sit'
})
test('Custom Delimiter', function() {
assert.deepEqual(flatten({
hello: {
world: {
again: 'good morning'
}
}
}, {
delimiter: ':'
}), {
'hello:world:again': 'good morning'
})
})
test('Custom Delimiter', function() {
assert.deepEqual(flatten({
hello: {
world: {
again: 'good morning'
}
}
}, {
delimiter: ':'
}), {
'hello:world:again': 'good morning'
})
})
})
suite('Unflatten', function() {
test('Nested once', function() {
assert.deepEqual({
hello: {
world: 'good morning'
}
}, unflatten({
'hello.world': 'good morning'
}))
test('Nested once', function() {
assert.deepEqual({
hello: {
world: 'good morning'
}
}, unflatten({
'hello.world': 'good morning'
}))
})
test('Nested twice', function() {
assert.deepEqual({
hello: {
world: {
again: 'good morning'
}
}
}, unflatten({
'hello.world.again': 'good morning'
}))
})
test('Multiple Keys', function() {
assert.deepEqual({
hello: {
lorem: {
ipsum: 'again',
dolor: 'sit'
}
},
world: {
lorem: {
ipsum: 'again',
dolor: 'sit'
}
}
}, unflatten({
'hello.lorem.ipsum': 'again',
'hello.lorem.dolor': 'sit',
'world.lorem.ipsum': 'again',
'world.lorem.dolor': 'sit'
}))
})
test('Custom Delimiter', function() {
assert.deepEqual({
hello: {
world: {
again: 'good morning'
}
}
}, unflatten({
'hello world again': 'good morning'
}, {
delimiter: ' '
}))
})
test('Messy', function() {
assert.deepEqual({
hello: { world: 'again' },
lorem: { ipsum: 'another' },
good: {
morning: {
hash: {
key: { nested: {
deep: { and: { even: {
deeper: { still: 'hello' }
} } }
} }
},
again: { testing: { 'this': 'out' } }
}
}
}, unflatten({
'hello.world': 'again',
'lorem.ipsum': 'another',
'good.morning': {
'hash.key': {
'nested.deep': {
'and.even.deeper.still': 'hello'
}
}
},
'good.morning.again': {
'testing.this': 'out'
}
}))
})
suite('.safe', function() {
test('Should protect arrays when true', function() {
assert.deepEqual(flatten({
hello: [
{ world: { again: 'foo' } }
, { lorem: 'ipsum' }
]
, another: {
nested: [{ array: { too: 'deep' }}]
}
, lorem: {
ipsum: 'whoop'
}
}, {
safe: true
}), {
hello: [
{ world: { again: 'foo' } }
, { lorem: 'ipsum' }
]
, 'lorem.ipsum': 'whoop'
, 'another.nested': [{ array: { too: 'deep' }}]
})
})
test('Nested twice', function() {
assert.deepEqual({
hello: {
world: {
again: 'good morning'
}
}
}, unflatten({
'hello.world.again': 'good morning'
}))
test('Should not protect arrays when false', function() {
assert.deepEqual(flatten({
hello: [
{ world: { again: 'foo' } }
, { lorem: 'ipsum' }
]
}, {
safe: false
}), {
'hello.0.world.again': 'foo'
, 'hello.1.lorem': 'ipsum'
})
})
test('Multiple Keys', function() {
assert.deepEqual({
hello: {
lorem: {
ipsum: 'again',
dolor: 'sit'
}
},
world: {
lorem: {
ipsum: 'again',
dolor: 'sit'
}
}
}, unflatten({
'hello.lorem.ipsum': 'again',
'hello.lorem.dolor': 'sit',
'world.lorem.ipsum': 'again',
'world.lorem.dolor': 'sit'
}))
})
test('Custom Delimiter', function() {
assert.deepEqual({
hello: {
world: {
again: 'good morning'
}
}
}, unflatten({
'hello world again': 'good morning'
}, {
delimiter: ' '
}))
})
test('Messy', function() {
assert.deepEqual({
hello: { world: 'again' },
lorem: { ipsum: 'another' },
good: {
morning: {
hash: {
key: { nested: {
deep: { and: { even: {
deeper: { still: 'hello' }
} } }
} }
},
again: { testing: { 'this': 'out' } }
}
}
}, unflatten({
'hello.world': 'again',
'lorem.ipsum': 'another',
'good.morning': {
'hash.key': {
'nested.deep': {
'and.even.deeper.still': 'hello'
}
}
},
'good.morning.again': {
'testing.this': 'out'
}
}))
})
})
suite('.safe', function() {
test('Should protect arrays when true', function() {
assert.deepEqual(flatten({
hello: [
{ world: { again: 'foo' } }
, { lorem: 'ipsum' }
]
, another: {
nested: [{ array: { too: 'deep' }}]
}
, lorem: {
ipsum: 'whoop'
}
}, {
safe: true
}), {
hello: [
{ world: { again: 'foo' } }
, { lorem: 'ipsum' }
]
, 'lorem.ipsum': 'whoop'
, 'another.nested': [{ array: { too: 'deep' }}]
})
})
test('Should not protect arrays when false', function() {
assert.deepEqual(flatten({
hello: [
{ world: { again: 'foo' } }
, { lorem: 'ipsum' }
]
}, {
safe: false
}), {
'hello.0.world.again': 'foo'
, 'hello.1.lorem': 'ipsum'
})
})
suite('.object', function() {
test('Should create object instead of array when true', function() {
assert.deepEqual({
hello: {
you: {
0: 'ipsum',
1: 'lorem',
},
other: { world: 'foo' }
}
}, unflatten(
{
'hello.you.0': 'ipsum',
'hello.you.1': 'lorem',
'hello.other.world': 'foo'
}, {
object: true
}))
})
suite('.object', function() {
test('Should create object instead of array when true', function() {
assert.deepEqual({
hello: {
you: {
0: 'ipsum',
1: 'lorem',
},
other: { world: 'foo' }
}
}, unflatten(
{
'hello.you.0': 'ipsum',
'hello.you.1': 'lorem',
'hello.other.world': 'foo'
}, {
object: true
}));
})
test('Should not create object when false', function() {
assert.deepEqual({
hello: {
you: ['ipsum', 'lorem'],
other: { world: 'foo' }
}
}, unflatten(
{
'hello.you.0': 'ipsum',
'hello.you.1': 'lorem',
'hello.other.world': 'foo'
}, {
object: false
}));
})
test('Should not create object when false', function() {
assert.deepEqual({
hello: {
you: ['ipsum', 'lorem'],
other: { world: 'foo' }
}
}, unflatten(
{
'hello.you.0': 'ipsum',
'hello.you.1': 'lorem',
'hello.other.world': 'foo'
}, {
object: false
}))
})
});
})
})
suite('Arrays', function() {
var object, flatObject;
object = { "a": ["foo", "bar"] };
flatObject = { "a.0": "foo", "a.1": "bar"};
test('Should be able to flatten arrays properly', function() {
assert.deepEqual({
'a.0': 'foo'
, 'a.1': 'bar'
}, flatten({
a: ['foo', 'bar']
}))
})
test('Should be able to flatten arrays properly', function() {
assert.deepEqual(flatObject, flatten(object));
});
test('Should be able to revert and reverse array serialization via unflatten', function() {
assert.deepEqual(object, unflatten(flatObject));
});
test('Array typed objects should be restored by unflatten', function () {
assert.equal(Object.prototype.toString.call(object.a), Object.prototype.toString.call(unflatten(flatObject).a));
test('Should be able to revert and reverse array serialization via unflatten', function() {
assert.deepEqual({
a: ['foo', 'bar']
}, unflatten({
'a.0': 'foo'
, 'a.1': 'bar'
}))
})
test('Array typed objects should be restored by unflatten', function () {
assert.equal(
Object.prototype.toString.call(['foo', 'bar'])
, Object.prototype.toString.call(unflatten({
'a.0': 'foo'
, 'a.1': 'bar'
}).a)
)
})
test('Do not include keys with numbers inside them', function() {
assert.deepEqual(unflatten({
'1key.2_key': 'ok'
}), {
'1key': {
'2_key': 'ok'
}
})
});
})
})
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