From 24a2e75fa30804e5a16fa23c55c4f56a446f91e1 Mon Sep 17 00:00:00 2001 From: Opender Singh Date: Thu, 30 May 2019 08:10:48 +1200 Subject: [PATCH] Preserve property order in environment editor (#1497) * Add json-order package * Add propertyMap and sort properties boolean to model * Keep property order * Remove extra check * Allow env editor in request group overrides to maintain order * Add checkbox * Order control added * Use up to date json-order * Rename * Remove extra field * Update separator * Prevent unnecessary parse * Move to regular dependency * add to packedDeps * Renames * Remove extra code * Removed extra state * More fixes... * add flowtypes for json-order * typo * Updated flowtypes * Fixed? * linting to remove unused import --- package-lock.json | 92 ++++++++++++++----- .../insomnia-app/app/models/environment.js | 2 + .../insomnia-app/app/models/request-group.js | 2 + .../components/editors/environment-editor.js | 26 ++++-- .../modals/environment-edit-modal.js | 21 ++++- .../workspace-environments-edit-modal.js | 81 ++++++++-------- .../ui/css/components/environment-editor.less | 2 + .../insomnia-app/flow-typed/json-order.js | 20 ++++ packages/insomnia-app/package-lock.json | 77 +++++++++++++--- packages/insomnia-app/package.json | 2 + 10 files changed, 244 insertions(+), 81 deletions(-) create mode 100644 packages/insomnia-app/flow-typed/json-order.js diff --git a/package-lock.json b/package-lock.json index c8e2047cbbf..99b78932f7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,6 +74,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -111,7 +112,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -132,12 +134,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -152,17 +156,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -279,7 +286,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -291,6 +299,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -305,6 +314,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -312,12 +322,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -336,6 +348,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -416,7 +429,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -428,6 +442,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -513,7 +528,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -549,6 +565,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -568,6 +585,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -611,12 +629,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -647,7 +667,8 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "dev": true, + "optional": true }, "is-glob": { "version": "4.0.1", @@ -8846,7 +8867,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -8867,12 +8889,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -8887,17 +8911,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -9014,7 +9041,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -9026,6 +9054,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -9040,6 +9069,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -9047,12 +9077,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -9071,6 +9103,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -9151,7 +9184,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -9163,6 +9197,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -9248,7 +9283,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -9284,6 +9320,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -9303,6 +9340,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -9346,12 +9384,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -14933,7 +14973,8 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true + "dev": true, + "optional": true }, "braces": { "version": "2.3.2", @@ -15196,7 +15237,8 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "dev": true, + "optional": true }, "micromatch": { "version": "3.1.10", diff --git a/packages/insomnia-app/app/models/environment.js b/packages/insomnia-app/app/models/environment.js index ee97d8740f9..af86c6c3afd 100644 --- a/packages/insomnia-app/app/models/environment.js +++ b/packages/insomnia-app/app/models/environment.js @@ -13,6 +13,7 @@ export const canSync = true; type BaseEnvironment = { name: string, data: Object, + dataPropertyOrder: Object | null, color: string | null, metaSortKey: number, @@ -26,6 +27,7 @@ export function init() { return { name: 'New Environment', data: {}, + dataPropertyOrder: null, color: null, isPrivate: false, metaSortKey: Date.now(), diff --git a/packages/insomnia-app/app/models/request-group.js b/packages/insomnia-app/app/models/request-group.js index 16919507d09..3da52893f79 100644 --- a/packages/insomnia-app/app/models/request-group.js +++ b/packages/insomnia-app/app/models/request-group.js @@ -12,6 +12,7 @@ type BaseRequestGroup = { name: string, description: string, environment: Object, + environmentPropertyOrder: Object | null, metaSortKey: number, }; @@ -22,6 +23,7 @@ export function init() { name: 'New Folder', description: '', environment: {}, + environmentPropertyOrder: null, metaSortKey: -1 * Date.now(), }; } diff --git a/packages/insomnia-app/app/ui/components/editors/environment-editor.js b/packages/insomnia-app/app/ui/components/editors/environment-editor.js index d4d4cbc4680..908e3d2bfe2 100644 --- a/packages/insomnia-app/app/ui/components/editors/environment-editor.js +++ b/packages/insomnia-app/app/ui/components/editors/environment-editor.js @@ -2,9 +2,15 @@ import * as React from 'react'; import autobind from 'autobind-decorator'; import CodeEditor from '../codemirror/code-editor'; +import orderedJSON from 'json-order'; + +export type EnvironmentInfo = { + object: Object, + propertyOrder: Object | null, +}; type Props = { - environment: Object, + environmentInfo: EnvironmentInfo, didChange: Function, editorFontSize: number, editorIndentSize: number, @@ -69,11 +75,16 @@ class EnvironmentEditor extends React.PureComponent { this._editor = n; } - getValue() { + getValue(): EnvironmentInfo | null { if (this._editor) { - return JSON.parse(this._editor.getValue()); + const data = orderedJSON.parse(this._editor.getValue(), '&', `~|`); + + return { + object: data.object, + propertyOrder: data.map || null, + }; } else { - return ''; + return null; } } @@ -83,7 +94,7 @@ class EnvironmentEditor extends React.PureComponent { render() { const { - environment, + environmentInfo, editorFontSize, editorIndentSize, editorKeyMap, @@ -107,7 +118,10 @@ class EnvironmentEditor extends React.PureComponent { lineWrapping={lineWrapping} keyMap={editorKeyMap} onChange={this._handleChange} - defaultValue={JSON.stringify(environment)} + defaultValue={orderedJSON.stringify( + environmentInfo.object, + environmentInfo.propertyOrder || null, + )} nunjucksPowerUserMode={nunjucksPowerUserMode} isVariableUncovered={isVariableUncovered} render={render} diff --git a/packages/insomnia-app/app/ui/components/modals/environment-edit-modal.js b/packages/insomnia-app/app/ui/components/modals/environment-edit-modal.js index c686338ac83..302a4cd7f82 100644 --- a/packages/insomnia-app/app/ui/components/modals/environment-edit-modal.js +++ b/packages/insomnia-app/app/ui/components/modals/environment-edit-modal.js @@ -30,10 +30,20 @@ class EnvironmentEditModal extends PureComponent { return; } - const environment = this._envEditor.getValue(); + let patch; + try { + const data = this._envEditor.getValue(); + patch = { + environment: data && data.object, + environmentPropertyOrder: data && data.propertyOrder, + }; + } catch (err) { + // Invalid JSON probably + return; + } const { requestGroup } = this.state; - this.props.onChange(Object.assign({}, requestGroup, { environment })); + this.props.onChange(Object.assign({}, requestGroup, patch)); } _didChange() { @@ -70,6 +80,11 @@ class EnvironmentEditModal extends PureComponent { const { requestGroup, isValid } = this.state; + const environmentInfo = { + object: requestGroup ? requestGroup.environment : {}, + propertyOrder: requestGroup && requestGroup.environmentPropertyOrder, + }; + return ( Environment Overrides (JSON Format) @@ -81,7 +96,7 @@ class EnvironmentEditModal extends PureComponent { ref={this._setEditorRef} key={requestGroup ? requestGroup._id : 'n/a'} lineWrapping={lineWrapping} - environment={requestGroup ? requestGroup.environment : {}} + environmentInfo={environmentInfo} didChange={this._didChange} render={render} getRenderContext={getRenderContext} diff --git a/packages/insomnia-app/app/ui/components/modals/workspace-environments-edit-modal.js b/packages/insomnia-app/app/ui/components/modals/workspace-environments-edit-modal.js index a9b1d401174..c4828ad216e 100644 --- a/packages/insomnia-app/app/ui/components/modals/workspace-environments-edit-modal.js +++ b/packages/insomnia-app/app/ui/components/modals/workspace-environments-edit-modal.js @@ -342,9 +342,13 @@ class WorkspaceEnvironmentsEditModal extends React.PureComponent { return; } - let data; + let patch; try { - data = this.environmentEditorRef.getValue(); + const data = this.environmentEditorRef.getValue(); + patch = { + data: data && data.object, + dataPropertyOrder: data && data.propertyOrder, + }; } catch (err) { // Invalid JSON probably return; @@ -355,7 +359,7 @@ class WorkspaceEnvironmentsEditModal extends React.PureComponent { if (activeEnvironment) { clearTimeout(this.saveTimeout); this.saveTimeout = setTimeout(() => { - models.environment.update(activeEnvironment, { data }); + models.environment.update(activeEnvironment, patch); }, DEBOUNCE_MILLIS * 4); } } @@ -376,6 +380,11 @@ class WorkspaceEnvironmentsEditModal extends React.PureComponent { const activeEnvironment = this._getActiveEnvironment(); + const environmentInfo = { + object: activeEnvironment ? activeEnvironment.data : {}, + propertyOrder: activeEnvironment && activeEnvironment.dataPropertyOrder, + }; + return ( Manage Environments @@ -441,39 +450,39 @@ class WorkspaceEnvironmentsEditModal extends React.PureComponent { {activeEnvironment && rootEnvironment !== activeEnvironment ? ( - - - {activeEnvironment.color && ( - - )} - Color - - - - - {activeEnvironment.color ? 'Change Color' : 'Assign Color'} - - - + + + {activeEnvironment.color && ( + + )} + Color + + + + + {activeEnvironment.color ? 'Change Color' : 'Assign Color'} + + + + + Unset Color + + + + - - Unset Color - - - ) : null} - - {activeEnvironment && rootEnvironment !== activeEnvironment ? ( - - - + onClick={this._handleDeleteEnvironment} + className="btn btn--clicky"> + + + ) : null}
@@ -484,7 +493,7 @@ class WorkspaceEnvironmentsEditModal extends React.PureComponent { lineWrapping={lineWrapping} ref={this._setEditorRef} key={`${this.editorKey}::${activeEnvironment ? activeEnvironment._id : 'n/a'}`} - environment={activeEnvironment ? activeEnvironment.data : {}} + environmentInfo={environmentInfo} didChange={this._didChange} render={render} getRenderContext={getRenderContext} diff --git a/packages/insomnia-app/app/ui/css/components/environment-editor.less b/packages/insomnia-app/app/ui/css/components/environment-editor.less index beb522b7cf7..b2e8c71c3df 100644 --- a/packages/insomnia-app/app/ui/css/components/environment-editor.less +++ b/packages/insomnia-app/app/ui/css/components/environment-editor.less @@ -1,3 +1,5 @@ +@import '../constants/dimensions.less'; + .environment-editor { display: grid; grid-template-rows: 1fr auto; diff --git a/packages/insomnia-app/flow-typed/json-order.js b/packages/insomnia-app/flow-typed/json-order.js new file mode 100644 index 00000000000..dd8b3d198b0 --- /dev/null +++ b/packages/insomnia-app/flow-typed/json-order.js @@ -0,0 +1,20 @@ +// @flow + +declare module 'json-order' { + declare type OrderedParseResult = { + object: Object, + map: { [key: string]: Array }, + }; + + declare type orderedJSON = { + parse: (jsonString: string, prefix?: string, separator?: string) => OrderedParseResult, + stringify: ( + sourceObject: Object, + map: { [key: string]: Array } | null, + separator?: string, + space?: number | void, + ) => string, + }; + + declare module.exports: orderedJSON; +} diff --git a/packages/insomnia-app/package-lock.json b/packages/insomnia-app/package-lock.json index 3cdcb29f8e8..77bd5428713 100644 --- a/packages/insomnia-app/package-lock.json +++ b/packages/insomnia-app/package-lock.json @@ -2647,6 +2647,11 @@ "buffer-indexof": "^1.0.0" } }, + "docopt": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/docopt/-/docopt-0.6.2.tgz", + "integrity": "sha1-so6eIiDaXsSffqW7JKR3h0Be6xE=" + }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -2703,6 +2708,15 @@ "domelementtype": "1" } }, + "dot-json": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/dot-json/-/dot-json-1.1.0.tgz", + "integrity": "sha512-PiQZW9/C8xILPYK2bOye/cbPZrakNEkt28jFb8RlPCwsoMAHYYw9T8JoACxgttHL9Y2AmdqVvibbZJHtLgeqTQ==", + "requires": { + "docopt": "~0.6.2", + "underscore-keypath": "~0.0.22" + } + }, "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", @@ -4868,7 +4882,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -4888,11 +4903,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4906,15 +4923,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5030,7 +5050,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5041,6 +5062,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5054,17 +5076,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5082,6 +5107,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5161,7 +5187,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5172,6 +5199,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5256,7 +5284,8 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5291,6 +5320,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5309,6 +5339,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5351,11 +5382,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.0.3", - "bundled": true + "bundled": true, + "optional": true } } }, @@ -7260,6 +7293,15 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json-order": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/json-order/-/json-order-1.0.9.tgz", + "integrity": "sha512-MiULsoJSkszrEdyWyaecNvJ7m0EJvYDqJ0NjVUoU8NRKuTo9OcFDCDOLyGA/qOQ3+FTJpF2vdjggiPKP+6Aa/A==", + "requires": { + "dot-json": "^1.1.0", + "lodash.clonedeep": "^4.5.0" + } + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -7719,6 +7761,11 @@ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", "dev": true }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -11711,6 +11758,14 @@ } } }, + "underscore-keypath": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/underscore-keypath/-/underscore-keypath-0.0.22.tgz", + "integrity": "sha1-SKUoOSu278QkvhyqVtpLX6zPJk0=", + "requires": { + "underscore": "*" + } + }, "union-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", diff --git a/packages/insomnia-app/package.json b/packages/insomnia-app/package.json index 9766061cf85..65414d78913 100644 --- a/packages/insomnia-app/package.json +++ b/packages/insomnia-app/package.json @@ -77,6 +77,7 @@ "insomnia-url", "insomnia-xpath", "highlight.js", + "json-order", "jwt-authentication", "moment", "nunjucks", @@ -133,6 +134,7 @@ "insomnia-prettify": "^0.1.11", "insomnia-url": "^0.1.10", "insomnia-xpath": "^1.0.13", + "json-order": "^1.0.9", "jsonlint": "^1.6.3", "jsonpath": "^0.2.12", "jwt-authentication": "^0.4.0",