{"id":19889537,"url":"https://github.com/tsmx/json-traverse","last_synced_at":"2025-06-11T01:08:19.025Z","repository":{"id":57168114,"uuid":"299585273","full_name":"tsmx/json-traverse","owner":"tsmx","description":"Traverse and manipulate JSON objects.","archived":false,"fork":false,"pushed_at":"2025-03-17T20:09:50.000Z","size":725,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-01T10:52:22.028Z","etag":null,"topics":["json","traverse"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tsmx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-29T10:40:35.000Z","updated_at":"2025-03-17T20:09:53.000Z","dependencies_parsed_at":"2023-01-30T01:45:58.898Z","dependency_job_id":"ef7f9fae-2f89-45e1-b44e-eb53018e029d","html_url":"https://github.com/tsmx/json-traverse","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmx%2Fjson-traverse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmx%2Fjson-traverse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmx%2Fjson-traverse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmx%2Fjson-traverse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tsmx","download_url":"https://codeload.github.com/tsmx/json-traverse/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmx%2Fjson-traverse/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259178497,"owners_count":22817387,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json","traverse"],"created_at":"2024-11-12T18:10:39.365Z","updated_at":"2025-06-11T01:08:19.003Z","avatar_url":"https://github.com/tsmx.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [**@tsmx/json-traverse**](https://github.com/tsmx/json-traverse)\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n![npm (scoped)](https://img.shields.io/npm/v/@tsmx/json-traverse)\n![node-current (scoped)](https://img.shields.io/node/v/@tsmx/json-traverse)\n[![Build Status](https://img.shields.io/github/actions/workflow/status/tsmx/json-traverse/git-build.yml?branch=master)](https://img.shields.io/github/actions/workflow/status/tsmx/json-traverse/git-build.yml?branch=master)\n[![Coverage Status](https://coveralls.io/repos/github/tsmx/json-traverse/badge.svg?branch=master)](https://coveralls.io/github/tsmx/json-traverse?branch=master)\n\n\u003e Traverse and manipulate JSON objects.\n\n## Usage\n\n### Basic usage\n\n```js\nconst jt = require('@tsmx/json-traverse');\n\nconst callbacks = {\n    processValue: (key, value, level, path, isObjectRoot, isArrayElement, cbSetValue) =\u003e { \n            /* your logic here */ \n        },\n    enterLevel: (level, path) =\u003e { \n            /* your logic here */ \n        },\n    exitLevel: (level, path) =\u003e { \n            /* your logic here */ \n        }\n};\n\nvar obj = { /* your JSON object */ };\n\njt.traverse(obj, callbacks);\n```\n\n### Example 1: print out a simple object\n\n```js\nvar simpleObj = {\n    MyValue: 'test',\n    OtherValue: 'zzz',\n    NumberValue: 311,\n    MyArray: [1, 2, 3, 50, 60, 70]\n};\n\nconst callbacks = {\n    processValue: (key, value, level, path, isObjectRoot, isArrayElement, cbSetValue) =\u003e { \n        console.log(level + ' ' + (path.length \u003e 0 ? (path.join('.') + '.') : '') + key + ' = ' + value); \n    }\n};\n\nconst jt = require('@tsmx/json-traverse');\n\njt.traverse(simpleObj, callbacks);\n// 0 MyValue = test\n// 0 OtherValue = xxx\n// 0 NumberValue = 311\n// 0 MyArray._0 = 1\n// 0 MyArray._1 = 2\n// 0 MyArray._2 = 3\n// 0 MyArray._3 = 50\n// 0 MyArray._4 = 60\n// 0 MyArray._5 = 70\n\n// flat array-mode: flattenArray = true (arrays are treated as one value)\njt.traverse(simpleObj, callbacks, true);\n// 0 MyValue = test\n// 0 OtherValue = xxx\n// 0 NumberValue = 311\n// 0 MyArray = 1,2,3,50,60,70\n```\n\n### Example 2: change values of an object\n\n```js\nvar simpleObj = {\n    MyValue: 'test',\n    OtherValue: 'zzz',\n    NumberValue: 311,\n    MyArray: [1, 2, 3, 50, 60, 70]\n};\n\nconst callbacks = {\n    processValue: (key, value, level, path, isObjectRoot, isArrayElement, cbSetValue) =\u003e { \n        // change values of properties starting with 'My' and\n        // multiply all numeric array values greater then 50 by 100\n        if (key.startsWith('My')) {\n            cbSetValue('MyNew-' + value);\n        }\n        if (isArrayElement \u0026\u0026 parseInt(value) \u003e 50) {\n            cbSetValue(100 * parseInt(value));\n        }\n    }\n};\n\nconst jt = require('@tsmx/json-traverse');\n\njt.traverse(simpleObj, callbacks);\n\n// {\n//   MyValue : \"MyNew-test\",\n//   OtherValue: \"xxx\",\n//   NumberValue: 311,\n//   MyArray: [ 1, 2, 3, 50, 6000, 7000 ]\n// }\n```\n\n### Example 3: convert a more complex object to a collapsible HTML list\n\n```js\nvar htmlObj = {\n    MyArray: [0, 0],\n    ArrayInArray: [0, 1, ['two', 'three', [4, 5, 6]]],\n    MyNumber: 123,\n    MyString: 'test',\n    Child: {\n        ChildVal: 1,\n        SubChild: {\n            SubChildVal: 777\n        },\n        ChildArray: [1, 2, 66, 9, 900]\n    },\n    TrailingValue: 'testtesttest'\n}\n\nconst callbacksHtmlList = {\n    processValue: (key, value, level, path, isObjectRoot, isArrayElement, cbSetValue) =\u003e {\n        if (isObjectRoot) {\n            console.log(('  ').repeat(level) + ' \u003cli class=\\\"caret\\\"\u003eKey: ' + key + '\u003c/li\u003e')\n        }\n        else {\n            console.log(('  ').repeat(level) + ' \u003cli\u003eKey: ' + key + ', Value: ' + value + '\u003c/li\u003e')\n        };\n    },\n    enterLevel: (level, path) =\u003e {\n        if (level == 0) {\n            console.log('\u003cul\u003e');\n        }\n        else {\n            console.log(('  ').repeat(level) + '\u003cul class=\\\"nested\\\"\u003e');\n        };\n    },\n    exitLevel: (level, path) =\u003e { console.log(('  ').repeat(level) + '\u003c/ul\u003e'); }\n};\n\nconst jt = require('@tsmx/json-traverse');\n\njt.traverse(htmlObj, callbacksHtmlList, true);\n\n// \u003cul\u003e\n//  \u003cli\u003eKey: MyArray, Value: 0,0\u003c/li\u003e\n//  \u003cli\u003eKey: ArrayInArray, Value: 0,1,two,three,4,5,6\u003c/li\u003e\n//  \u003cli\u003eKey: MyNumber, Value: 123\u003c/li\u003e\n//  \u003cli\u003eKey: MyString, Value: test\u003c/li\u003e\n//  \u003cli class=\"caret\"\u003eKey: Child\u003c/li\u003e\n//   \u003cul class=\"nested\"\u003e\n//    \u003cli\u003eKey: ChildVal, Value: 1\u003c/li\u003e\n//    \u003cli class=\"caret\"\u003eKey: SubChild\u003c/li\u003e\n//     \u003cul class=\"nested\"\u003e\n//      \u003cli\u003eKey: SubChildVal, Value: 777\u003c/li\u003e\n//     \u003c/ul\u003e\n//    \u003cli\u003eKey: ChildArray, Value: 1,2,66,9,900\u003c/li\u003e\n//   \u003c/ul\u003e\n//  \u003cli\u003eKey: TrailingValue, Value: testtesttest\u003c/li\u003e\n// \u003c/ul\u003e\n\n```\n\n## Key-features\n\n- Define your callbacks for the following events:\n  - `processValue`: processing a traversed value\n  - `enterLevel`: entering a new nesting level\n  - `exitLevel`: leaving nesting level\n- For every inspected value you will get rich meta-data\n  - key name\n  - level of nesting\n  - `isObjectRoot` flag to indicate if it's an object root (root of a nested object)\n  - `isArrayElement` flag to indicate if it's an array item\n  - full path to the key as an array of path elements\n- Provides `cbSetValue` function to change any value in-place (directly in the traversed object)\n- Supports deep inspection of\n  - Subobjects\n  - Arrays\n  - Arrays-in-Arrays\n  - Subobjects-in-Arrays\n- Optional array flattening (treat arrays as flat values)\n\n## API\n\n### traverse(obj, callbacks = null, flattenArray = false)\n\nTraverse the `obj` and apply the defined callbacks while traversing.\n\n#### obj\n\nType: `Object`\n\nThe object to be traversed.\n\n#### callbacks\n\nType: `Object`\nDefault: `null`\n\nAn Object containing the callback functions that should be applied while traversing `obj`. Every callback is optional. The expected form is:\n\n```js\ncallbacks = {\n    processValue: (key, value, level, path, isObjectRoot, isArrayElement, cbSetValue) =\u003e { \n            /* your logic here */ \n        },\n    enterLevel: (level, path) =\u003e { \n            /* your logic here */ \n        },\n    exitLevel: (level, path) =\u003e { \n            /* your logic here */ \n        }\n};\n```\n\n##### processValue(key, value, level, path, isObjectRoot, isArrayElement, cbSetValue)\n\nDefined callback function that is executed on each value when traversing the object. Receives the following input parameters:\n\n###### key\n\nType: `String`\n\nThe key of the current value that is processed. If an array is deep-inspected the key for each processed item is `_ + Index` (`_0`, `_1`, `_2`,...).\n\n###### value\n\nType: `String`\n\nThe actual value for `key`.\n\n###### level\n\nType: `Number`\n\nThe nesting level. `0` indicates the first level.\n\n###### path\n\nType: `Array`\n\nAn array containing all keys that where passed to reach the current key/value pair. Example:\n\n```js\n{\n    child: {\n        subchild: {\n            myvalue: 123;\n        }\n    }\n}\n```\n\nWhen processing the value `123` with key `myvalue`, path would be `['child', 'subchild' ]`. \n\nFor deep-inspected arrays the path would contain the name of the array itself whereas the key would be the index of the processed value. Example:\n\n```js\n{\n    child: {\n        subchild: {\n            myvalues: [1, 2, 3]\n        }\n    }\n}\n```\n\nWhen processing the array the keys would be `_0`, `_1` and `_2` and the path would always be `['child', 'subchild', 'myvalues']`.\n\n###### isObjectRoot\n\nType: `Boolean`\n\n`true` if the currently processed key is the root of another sub-object. In our example:\n\n```js\n{\n    child: {\n        subchild: {\n            myvalue: 123;\n        }\n    }\n}\n```\n\n`isObjectRoot` would be `true` for the keys `child` and `subchild`.\n\n###### isArrayElement\n\nType: `Boolean`\n\n`true` if the currently processed key is an item of an array.\n\n###### cbSetValue(newValue)\n\nType: `Function`\n\nCallback function receiving the `newValue` that should replace the currently traversed `value`.\n\n**Note:** Setting a new value directly changes the traversed object! So if you need the original later on be sure to create a copy of the object first.\n\n##### enterLevel(level, path)\n\nDefined callback function that is executed on entering a new nesting level when traversing the object. Receives the following input parameters:\n\n###### level\n\nType: `Number`\n\n0-based index of the nesting level that is entered.\n\n###### path\n\nType: `Array`\n\nAn array containing all keys that where passed to reach the current level that is entered.\n\n##### exitLevel(level, path)\n\nDefined callback function that is executed on leaving a nesting level when traversing the object. Receives the following input parameters:\n\n###### level\n\nType: `Number`\n\n0-based index of the nesting level that is exited.\n\n###### path\n\nType: `Array`\n\nAn array containing all keys that where passed to reach the current level that is exited.\n\n#### flattenArray\n\nType: `Boolean`\nDefault: `false`\n\nIf set to `true` arrays will not be iterated but treated as one single value. The default is `false`, where arrays are iterated and each entry is processed separately including deep-inspection, e.g. if the entry is an object or another array.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsmx%2Fjson-traverse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftsmx%2Fjson-traverse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsmx%2Fjson-traverse/lists"}