From 065e6d560ebba230fbb674c2a650b6474903378f Mon Sep 17 00:00:00 2001 From: Lukas Siemon Date: Mon, 25 Jul 2022 10:18:53 -0700 Subject: [PATCH] feat: added nodeSeparator option --- README.md | 19 +++++++++++++------ src/index.js | 14 +++++++++++--- test/index.spec.js | 3 ++- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c45df2b..e29be49 100644 --- a/README.md +++ b/README.md @@ -84,37 +84,44 @@ By default a single string is returned. Can be set to `false` to instead return #### spacerNoNeighbour Type: `string`
-Default: ` ` +Default: `   ` Prefix for depth level when no further neighbour is present. #### spacerNeighbour Type: `string`
-Default: `│ ` +Default: `│  ` Prefix for depth level when a further neighbour is present. #### keyNoNeighbour Type: `string`
-Default: `└─ ` +Default: `└─ ` Prefix for key when no further neighbour is present. #### keyNeighbour Type: `string`
-Default: `├─ ` +Default: `├─ ` Prefix for key when a further neighbour is present. +#### nodeSeparator + +Type: `string`
+Default: `: ` + +Used to separate node key from node value. + #### renderFn Type: `function`
-Default: ``(node) => (['boolean', 'string', 'number'].includes(typeof node) ? `: ${node}` : '')`` +Default: `(node) => (['boolean', 'string', 'number'].includes(typeof node) ? node : undefined)` -Can be used to overwrite the node rendering logic. +Can be used to overwrite the node rendering logic. Node is rendered if result is not equal `undefined`. #### sortFn diff --git a/src/index.js b/src/index.js index 97a8f8f..dd2e06f 100644 --- a/src/index.js +++ b/src/index.js @@ -7,17 +7,19 @@ const buildCtx = (opts) => { spacerNeighbour: '│ ', keyNoNeighbour: '└─ ', keyNeighbour: '├─ ', - renderFn: (node) => (['boolean', 'string', 'number'].includes(typeof node) ? `: ${node}` : ''), + nodeSeparator: ': ', + renderFn: (node) => (['boolean', 'string', 'number'].includes(typeof node) ? node : undefined), sortFn: null, breakCircularWith: ' (circular ref.)', ...opts }; - assert(Object.keys(ctx).length === 8, 'Unexpected Option(s) provided'); + assert(Object.keys(ctx).length === 9, 'Unexpected Option(s) provided'); assert(typeof ctx.joined === 'boolean', 'Option "joined" has invalid format'); assert(typeof ctx.spacerNoNeighbour === 'string', 'Option "spacerNoNeighbour" has invalid format'); assert(typeof ctx.spacerNeighbour === 'string', 'Option "spacerNeighbour" has invalid format'); assert(typeof ctx.keyNoNeighbour === 'string', 'Option "keyNoNeighbour" has invalid format'); assert(typeof ctx.keyNeighbour === 'string', 'Option "keyNeighbour" has invalid format'); + assert(typeof ctx.nodeSeparator === 'string', 'Option "nodeSeparator" has invalid format'); assert(typeof ctx.renderFn === 'function', 'Option "renderFn" has invalid format'); assert(typeof ctx.sortFn === 'function' || ctx.sortFn === null, 'Option "sortFn" has invalid format'); assert( @@ -31,6 +33,11 @@ export default (tree, opts = {}) => { const ctx = buildCtx(opts); const result = []; + const rootRendered = ctx.renderFn(tree); + if (rootRendered !== undefined) { + result.push(String(rootRendered)); + } + const sort = (input) => (ctx.sortFn === null ? input.reverse() : input.sort((a, b) => ctx.sortFn(b, a))); const neighbours = []; @@ -42,11 +49,12 @@ export default (tree, opts = {}) => { const isCircular = ctx.breakCircularWith !== null && lookup.includes(node); neighbours[key.length - 1] = keys.length !== 0 && keys[keys.length - 1].length === key.length; + const nodeRendered = ctx.renderFn(node); result.push([ neighbours.slice(0, key.length - 1).map((n) => (n ? ctx.spacerNeighbour : ctx.spacerNoNeighbour)).join(''), neighbours[key.length - 1] ? ctx.keyNeighbour : ctx.keyNoNeighbour, key[key.length - 1], - ctx.renderFn(node), + nodeRendered === undefined ? '' : `${ctx.nodeSeparator}${node}`, isCircular ? ctx.breakCircularWith : '' ].join('')); diff --git a/test/index.spec.js b/test/index.spec.js index e16439d..c67d434 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -139,8 +139,9 @@ describe('Testing Treeify', () => { 9: null } }, { - renderFn: (node) => `: ${node}` + renderFn: (node) => node })).to.deep.equal([ + '[object Object]', '├─ 1: [object Object]', '│ ├─ 2: [object Object]', '│ │ └─ 3: null',