diff --git a/content/docs/latest/templating/mockoon-helpers.md b/content/docs/latest/templating/mockoon-helpers.md index a82cc6fc..d3c41a6b 100644 --- a/content/docs/latest/templating/mockoon-helpers.md +++ b/content/docs/latest/templating/mockoon-helpers.md @@ -1,5 +1,5 @@ --- -title: Custom helpers +title: Helpers meta: title: Create dynamic responses with templating helpers description: "Create dynamic fake data for your mock server with Mockoon's templating helpers. All formats are supported: JSON, CSV, HTML, etc." diff --git a/package-lock.json b/package-lock.json index a01b12ef..2e814704 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,9 @@ "glob": "^10.3.10", "gray-matter": "^4.0.3", "js-yaml": "^4.1.0", + "jsonpath-plus": "^8.1.0", "next": "^14.0.2", + "object-path": "^0.11.8", "raw-loader": "^4.0.2", "react": "^18.2.0", "react-bootstrap": "^2.9.1", @@ -611,22 +613,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@faker-js/faker": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-8.1.0.tgz", - "integrity": "sha512-38DT60rumHfBYynif3lmtxMqMqmsOQIxQgEuPZxCk2yUYN0eqWpTACgxi0VpidvsJB8CRxCpvP7B3anK85FjtQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/fakerjs" - } - ], - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0", - "npm": ">=6.14.13" - } - }, "node_modules/@firebase/analytics": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.0.tgz", @@ -1599,19 +1585,23 @@ "url": "https://mockoon.com/sponsor-us/" } }, - "node_modules/@mockoon/commons": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@mockoon/commons/-/commons-5.1.0.tgz", - "integrity": "sha512-g7g6OHy6VGS5bSRw5CQiU3E7fpCmFdnE2BiseSZaYs3OzORRLCBi0tPfUY3Fh2ZyFB/+UHABl35DchdCO3fqFA==", + "node_modules/@mockoon/cli/node_modules/@faker-js/faker": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-8.1.0.tgz", + "integrity": "sha512-38DT60rumHfBYynif3lmtxMqMqmsOQIxQgEuPZxCk2yUYN0eqWpTACgxi0VpidvsJB8CRxCpvP7B3anK85FjtQ==", "dev": true, - "dependencies": { - "joi": "17.10.2" - }, - "funding": { - "url": "https://mockoon.com/sponsor-us/" + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/fakerjs" + } + ], + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=6.14.13" } }, - "node_modules/@mockoon/commons-server": { + "node_modules/@mockoon/cli/node_modules/@mockoon/commons-server": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@mockoon/commons-server/-/commons-server-5.1.0.tgz", "integrity": "sha512-muI8w8al3cpKYDtECe/ZV0/O0l3n+GYLYyGWE/ZubUK5K67t26VcTKCfX4GkLJrW89hLeF3QfFJcIDn8+3UwLA==", @@ -1644,6 +1634,27 @@ "url": "https://mockoon.com/sponsor-us/" } }, + "node_modules/@mockoon/cli/node_modules/jsonpath-plus": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", + "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@mockoon/commons": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@mockoon/commons/-/commons-5.1.0.tgz", + "integrity": "sha512-g7g6OHy6VGS5bSRw5CQiU3E7fpCmFdnE2BiseSZaYs3OzORRLCBi0tPfUY3Fh2ZyFB/+UHABl35DchdCO3fqFA==", + "dev": true, + "dependencies": { + "joi": "17.10.2" + }, + "funding": { + "url": "https://mockoon.com/sponsor-us/" + } + }, "node_modules/@next/env": { "version": "14.0.2", "resolved": "https://registry.npmjs.org/@next/env/-/env-14.0.2.tgz", @@ -2148,9 +2159,9 @@ "integrity": "sha512-6i/8UoL0P5y4leBIGzvkZdS85RDMG9y1ihZzmTZQ5LdHUYmZ7pKFoj8X0236s3lusPs1Fa5HTQUpwI+UfTcmeA==" }, "node_modules/@sideway/address": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", - "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", "dev": true, "dependencies": { "@hapi/hoek": "^9.0.0" @@ -4791,13 +4802,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5836,16 +5852,19 @@ } }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-properties": { @@ -6229,6 +6248,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-iterator-helpers": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", @@ -7878,15 +7916,19 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8462,11 +8504,11 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9936,12 +9978,15 @@ } }, "node_modules/jsonpath-plus": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", - "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==", - "dev": true, + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-8.1.0.tgz", + "integrity": "sha512-qVTiuKztFGw0dGhYi3WNqvddx3/SHtyDT0xJaeyz4uP0d1tkpG+0y5uYQ4OcIo1TLAz3PE/qDOW9F0uDt3+CTw==", + "bin": { + "jsonpath": "bin/jsonpath-cli.js", + "jsonpath-plus": "bin/jsonpath-cli.js" + }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, "node_modules/jsonwebtoken": { @@ -12010,7 +12055,6 @@ "version": "0.11.8", "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.8.tgz", "integrity": "sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==", - "dev": true, "engines": { "node": ">= 10.12.0" } @@ -14015,14 +14059,16 @@ "optional": true }, "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -14076,13 +14122,17 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15811,9 +15861,9 @@ } }, "node_modules/winston-transport": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz", - "integrity": "sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", + "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", "dev": true, "dependencies": { "logform": "^2.3.2", @@ -16544,12 +16594,6 @@ "integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==", "peer": true }, - "@faker-js/faker": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-8.1.0.tgz", - "integrity": "sha512-38DT60rumHfBYynif3lmtxMqMqmsOQIxQgEuPZxCk2yUYN0eqWpTACgxi0VpidvsJB8CRxCpvP7B3anK85FjtQ==", - "dev": true - }, "@firebase/analytics": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.0.tgz", @@ -17331,6 +17375,47 @@ "mkdirp": "3.0.1", "mustache": "4.2.0", "tslib": "2.6.2" + }, + "dependencies": { + "@faker-js/faker": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-8.1.0.tgz", + "integrity": "sha512-38DT60rumHfBYynif3lmtxMqMqmsOQIxQgEuPZxCk2yUYN0eqWpTACgxi0VpidvsJB8CRxCpvP7B3anK85FjtQ==", + "dev": true + }, + "@mockoon/commons-server": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@mockoon/commons-server/-/commons-server-5.1.0.tgz", + "integrity": "sha512-muI8w8al3cpKYDtECe/ZV0/O0l3n+GYLYyGWE/ZubUK5K67t26VcTKCfX4GkLJrW89hLeF3QfFJcIDn8+3UwLA==", + "dev": true, + "requires": { + "@apidevtools/swagger-parser": "10.1.0", + "@faker-js/faker": "8.1.0", + "@mockoon/commons": "5.1.0", + "append-field": "1.0.0", + "busboy": "1.6.0", + "cookie-parser": "1.4.6", + "date-fns": "2.30.0", + "express": "4.18.2", + "handlebars": "4.7.8", + "http-proxy-middleware": "2.0.6", + "jsonpath-plus": "7.2.0", + "killable": "1.0.1", + "mime-types": "2.1.35", + "object-path": "0.11.8", + "qs": "6.11.2", + "range-parser": "1.2.1", + "typed-emitter": "2.1.0", + "winston": "3.10.0", + "xml-js": "1.6.11" + } + }, + "jsonpath-plus": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", + "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==", + "dev": true + } } }, "@mockoon/commons": { @@ -17342,33 +17427,6 @@ "joi": "17.10.2" } }, - "@mockoon/commons-server": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@mockoon/commons-server/-/commons-server-5.1.0.tgz", - "integrity": "sha512-muI8w8al3cpKYDtECe/ZV0/O0l3n+GYLYyGWE/ZubUK5K67t26VcTKCfX4GkLJrW89hLeF3QfFJcIDn8+3UwLA==", - "dev": true, - "requires": { - "@apidevtools/swagger-parser": "10.1.0", - "@faker-js/faker": "8.1.0", - "@mockoon/commons": "5.1.0", - "append-field": "1.0.0", - "busboy": "1.6.0", - "cookie-parser": "1.4.6", - "date-fns": "2.30.0", - "express": "4.18.2", - "handlebars": "4.7.8", - "http-proxy-middleware": "2.0.6", - "jsonpath-plus": "7.2.0", - "killable": "1.0.1", - "mime-types": "2.1.35", - "object-path": "0.11.8", - "qs": "6.11.2", - "range-parser": "1.2.1", - "typed-emitter": "2.1.0", - "winston": "3.10.0", - "xml-js": "1.6.11" - } - }, "@next/env": { "version": "14.0.2", "resolved": "https://registry.npmjs.org/@next/env/-/env-14.0.2.tgz", @@ -17728,9 +17786,9 @@ "integrity": "sha512-6i/8UoL0P5y4leBIGzvkZdS85RDMG9y1ihZzmTZQ5LdHUYmZ7pKFoj8X0236s3lusPs1Fa5HTQUpwI+UfTcmeA==" }, "@sideway/address": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", - "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", "dev": true, "requires": { "@hapi/hoek": "^9.0.0" @@ -19985,13 +20043,15 @@ } }, "call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" } }, "call-me-maybe": { @@ -20784,13 +20844,13 @@ } }, "define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "requires": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" } }, "define-properties": { @@ -21095,6 +21155,19 @@ "which-typed-array": "^1.1.13" } }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, "es-iterator-helpers": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", @@ -22378,10 +22451,11 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "requires": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", @@ -22823,11 +22897,11 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "requires": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" } }, "has-proto": { @@ -23887,10 +23961,9 @@ } }, "jsonpath-plus": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", - "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==", - "dev": true + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-8.1.0.tgz", + "integrity": "sha512-qVTiuKztFGw0dGhYi3WNqvddx3/SHtyDT0xJaeyz4uP0d1tkpG+0y5uYQ4OcIo1TLAz3PE/qDOW9F0uDt3+CTw==" }, "jsonwebtoken": { "version": "9.0.2", @@ -25382,8 +25455,7 @@ "object-path": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.8.tgz", - "integrity": "sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==", - "dev": true + "integrity": "sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==" }, "object-treeify": { "version": "1.1.33", @@ -26899,14 +26971,16 @@ "optional": true }, "set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "requires": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" } }, "set-function-name": { @@ -26945,13 +27019,14 @@ "dev": true }, "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" } }, "signal-exit": { @@ -28237,9 +28312,9 @@ } }, "winston-transport": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz", - "integrity": "sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", + "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", "dev": true, "requires": { "logform": "^2.3.2", diff --git a/package.json b/package.json index e8216e6c..a4492afe 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,9 @@ "glob": "^10.3.10", "gray-matter": "^4.0.3", "js-yaml": "^4.1.0", + "jsonpath-plus": "^8.1.0", "next": "^14.0.2", + "object-path": "^0.11.8", "raw-loader": "^4.0.2", "react": "^18.2.0", "react-bootstrap": "^2.9.1", diff --git a/pages/_document.tsx b/pages/_document.tsx index b243c4a5..8eff6fa0 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -12,7 +12,7 @@ class MyDocument extends Document { diff --git a/pages/tools/index.tsx b/pages/tools/index.tsx index 631fd24a..786b7cf3 100644 --- a/pages/tools/index.tsx +++ b/pages/tools/index.tsx @@ -43,6 +43,13 @@ const tools = [ 'Convert your data from JSON to YAML and back and verify their validity', links: [{ src: '/tools/json-to-yaml', text: 'Convert' }], imageSrc: '/images/illustrations/json-to-yaml.svg' + }, + { + title: 'JSONPath and object-path online evaluator', + description: + 'Extract values from JSON data using JSONPath or object-path syntaxes', + links: [{ src: '/tools/json-object-path-evaluator', text: 'Extract data' }], + imageSrc: '/images/illustrations/json-path-evaluator.svg' } ]; diff --git a/pages/tools/json-object-path-evaluator.tsx b/pages/tools/json-object-path-evaluator.tsx new file mode 100644 index 00000000..f9495823 --- /dev/null +++ b/pages/tools/json-object-path-evaluator.tsx @@ -0,0 +1,452 @@ +import { FunctionComponent, useState } from 'react'; +import CodeBlock from '../../components/code-block'; +import JsonEditor from '../../components/editors/json-editor'; +import Hero from '../../components/hero'; +import Meta from '../../components/meta'; +import Layout from '../../layout/layout'; +import { getValueFromPath } from '../../utils/tools'; + +const JsonPathPlayground: FunctionComponent = function () { + const [jsonContent, setJsonContent] = useState( + `{ + "property": { + "value": "example_value", + "list_of_properties": [ + { + "property_1": "value_1" + }, + { + "property_2": "value_2" + }, + { + "property_3": "value_3" + } + ], + "nested_properties": { + "nested_property": { + "nested_value": "nested_example_value" + } + }, + "multiple_values_for_property": [ + "value_1", + "value_2", + "value_3" + ] + } +}` + ); + const [extractedContent, setExtractedContent] = useState(`[ + "value_1" +]`); + + return ( + + + +
+
+ { + try { + setExtractedContent( + JSON.stringify( + getValueFromPath( + JSON.parse(jsonContent), + event.target.value, + '' + ), + null, + 2 + ) + ); + } catch (error) {} + }} + /> +

+ + Supports both{' '} + + JSONPath-plus + {' '} + and{' '} + + object-path + {' '} + syntaxes. Examples: $.property.value or{' '} + property.value + +

+
+
+
+
+ { + try { + setJsonContent(value); + setExtractedContent( + JSON.stringify( + getValueFromPath( + JSON.parse(value), + (document.querySelector('#path') as HTMLInputElement) + .value, + '' + ), + null, + 2 + ) + ); + } catch (error) {} + }} + /> +
+ +
+ +
+ + +
+
+
+ +
+
+
+
+

About this tool

+

+ This online tool allows you to extract values from JSON data + using{' '} + + JSONPath + {' '} + or{' '} + + object-path + {' '} + syntaxes. The extracted content is updated in real time as you + type your path. +

+

+ This playground uses the same logic as the Mockoon features that + support JSONPath and object-path syntaxes: +

+ + +

About JSONPath

+

+ JSONPath is a query language for JSON data. It allows you to + analyze, transform, and extract data from JSON documents. +
+ JSONPath is used in many programming languages and data + processing tools. It is similar to XPath for XML documents. +

+ +

Syntax cheat sheet

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SymbolDescription
$the root object/element
@the current object/element
. or []child operator
..nested descendants
* + wildcard, all objects/elements regardless of their names +
[]subscript operator
[,] + JSONPath allows alternate names or array indices as a set. +
[start:end:step]array slice operator
?()applies a filter (script) expression
+ +

JSONPath examples

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
JSONPathResult
+ $.store.book[*].author + the authors of all books in the store
+ $..author + all authors
+ $.store.* + + all things in store, which are some books and a red + bicycle +
+ $.store..price + the price of everything in the store
+ $..book[2] + the third book
+ $..book[(@.length-1)] +
+ $..book[-1:] +
the last book in order
+ $..book[0,1] +
+ $..book[:2] +
the first two books
+ $..book[?(@.isbn)] + filter all books with isbn number
+ {`$..book[?(@.price<10)]`} + filter all books cheapier than 10
+ $..* + All members of JSON data item
+ +

About object-path

+

+ object-path is a simpler library to access and manipulate + properties on objects using paths. It is similar to JSONPath but + less powerful and more straightforward to use. +
+ object-path is mainly using the dot and bracket notations to + access nested properties. However, it doesn't support all the + features of JSONPath. +

+ +

object-path examples

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
object-pathResult
+ store.book + + the books in the store, which are an array of objects +
+ store.bicycle.color + the color of the bicycle
+ store.book[0].author + the author of the first book
+ store.book[1].title + the title of the second book
+
+
+
+
+
+ ); +}; + +export default JsonPathPlayground; diff --git a/public/fonts/mockoon.woff b/public/fonts/mockoon.woff index 3657391b..01ff4666 100644 Binary files a/public/fonts/mockoon.woff and b/public/fonts/mockoon.woff differ diff --git a/public/images/illustrations/json-path-evaluator.svg b/public/images/illustrations/json-path-evaluator.svg new file mode 100644 index 00000000..22ea1ae1 --- /dev/null +++ b/public/images/illustrations/json-path-evaluator.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + $. + + + + diff --git a/styles/font.scss b/styles/font.scss index 00cf72f5..9f071e42 100644 --- a/styles/font.scss +++ b/styles/font.scss @@ -1,6 +1,6 @@ @font-face { font-family: 'mockoon'; - src: url('/fonts/mockoon.woff?dqmqhc') format('woff'); + src: url('/fonts/mockoon.woff?exgtff') format('woff'); font-weight: normal; font-style: normal; font-display: block; @@ -79,6 +79,9 @@ .icon-arrow_drop_down:before { content: '\e905'; } +.icon-arrow_forward:before { + content: '\e916'; +} .icon-check:before { content: '\e902'; } diff --git a/styles/mockoon.woff b/styles/mockoon.woff new file mode 100644 index 00000000..01ff4666 Binary files /dev/null and b/styles/mockoon.woff differ diff --git a/utils/tools.ts b/utils/tools.ts new file mode 100644 index 00000000..a8ecde94 --- /dev/null +++ b/utils/tools.ts @@ -0,0 +1,70 @@ +import { JSONPath } from 'jsonpath-plus'; +import { get as objectGet } from 'object-path'; + +// code taken from @mockoon/commons-server package as it contains node-specific code + +/** + * Convert an object path (for the object-path lib) containing escaped dots '\.' + * to an array of strings to allow fetching properties containing dots. + * + * Example: + * 'get.a.property\.with\.dots => ['get', 'a', 'property.with.dots'] + * + * To query an object like this: + * + * ``` + * { + * get: { + * a: { + * 'propery.with.dots': "value" + * } + * } + * } + * ``` + * @param str + */ +export const convertPathToArray = (str: string): string | string[] => { + if (str.includes('\\.')) { + return str + .replace(/\\\./g, '%#%') + .split('.') + .map((s) => s.replace(/%#%/g, '.')); + } + + return str; +}; + +/** + * Look for a value in an object or array using a path (dot notation or JSONPath). + * If no path is provided, return the full data. + * If the value is not found, return the default value. + * + * @param data + * @param path + * @param defaultValue + * @returns + */ +export const getValueFromPath = ( + data: any, + path: string, + defaultValue: any +) => { + if ( + (Array.isArray(data) || typeof data === 'object') && + typeof path === 'string' && + path !== '' + ) { + let foundValue: any; + + // Added wrap = false (Check https://github.com/mockoon/mockoon/issues/1297) + if (path.startsWith('$')) { + foundValue = JSONPath({ json: data, path: path, wrap: false }); + } else { + foundValue = objectGet(data, convertPathToArray(path)); + } + + return foundValue !== undefined ? foundValue : defaultValue; + } + + return data; +};