Skip to content

Commit

Permalink
feat: support multiple query languages in the transform modal (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
josdejong committed Nov 10, 2021
1 parent 8e5aecf commit 030d3ca
Show file tree
Hide file tree
Showing 16 changed files with 453 additions and 32 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ Or one-way binding:
}
}
function handleChange(updatedContent) {
function handleChange(updatedContent, previousContent, patchResult) {
// content is an object { json: JSON } | { text: string }
console.log('onChange: ', updatedContent)
console.log('onChange: ', updatedContent, previousContent, patchResult)
content = updatedContent
}
</script>
Expand Down Expand Up @@ -134,9 +134,9 @@ Browser example loading the ES module:
target: document.getElementById('jsoneditor'),
props: {
content,
onChange: (updatedContent) => {
onChange: (updatedContent, previousContent, patchResult) => {
// content is an object { json: JSON } | { text: string }
console.log('onChange', updatedContent)
console.log('onChange', updatedContent, previousContent, patchResult)
content = updatedContent
}
}
Expand Down Expand Up @@ -174,9 +174,9 @@ const editor = new JSONEditor({
target: document.getElementById('jsoneditor'),
props: {
content,
onChange: (updatedContent) => {
onChange: (updatedContent, previousContent, patchResult) => {
// content is an object { json: JSON } | { text: string }
console.log('onChange', updatedContent)
console.log('onChange', updatedContent, previousContent, patchResult)
}
}
})
Expand Down
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"debug": "^4.3.2",
"diff-sequences": "^27.0.6",
"immutable-json-patch": "^1.1.2",
"jmespath": "^0.15.0",
"json-source-map": "^0.6.1",
"jsonrepair": "^2.2.1",
"lodash-es": "^4.17.21",
Expand Down
16 changes: 16 additions & 0 deletions src/lib/components/JSONEditor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import AbsolutePopup from './modals/popup/AbsolutePopup.svelte'
import CodeMode from './modes/codemode/CodeMode.svelte'
import TreeMode from './modes/treemode/TreeMode.svelte'
import { lodashQueryLanguage } from '$lib/plugins/query/lodashQueryLanguage'
// TODO: document how to enable debugging in the readme: localStorage.debug="jsoneditor:*", then reload
const debug = createDebug('jsoneditor:Main')
Expand All @@ -31,6 +32,15 @@
export let navigationBar = true
export let validator = null
/** @type {QueryLanguage[]} */
export let queryLanguages
/** @type {string} */
export let queryLanguageId
/** @type {(queryLanguageId: string) => void} */
export let onChangeQueryLanguage
/** @type {((content: Content, previousContent: Content, patchResult: JSONPatchResult | null) => void) | null} */
export let onChange = null
Expand Down Expand Up @@ -281,6 +291,9 @@
{mainMenuBar}
{navigationBar}
{validator}
{queryLanguages}
{queryLanguageId}
{onChangeQueryLanguage}
onChange={handleChangeText}
onSwitchToTreeMode={handleSwitchToTreeMode}
{onError}
Expand All @@ -298,6 +311,9 @@
{mainMenuBar}
{navigationBar}
{validator}
{queryLanguages}
{queryLanguageId}
{onChangeQueryLanguage}
{onError}
onChange={handleChange}
onRequestRepair={handleRequestRepair}
Expand Down
14 changes: 13 additions & 1 deletion src/lib/components/modals/TransformModal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,19 @@
.description {
color: $dark-gray;

code {
:global(p) {
margin: $padding 0;

&:first-child {
margin-top: 0;
}

&:last-child {
margin-bottom: 0;
}
}

:global(code) {
background: $background-gray;
font-family: $font-family-mono;
font-size: $font-size-mono;
Expand Down
42 changes: 20 additions & 22 deletions src/lib/components/modals/TransformModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<script>
import { uniqueId } from '../../utils/uniqueId.js'
import { faCaretDown, faCaretRight } from '@fortawesome/free-solid-svg-icons'
import * as _ from 'lodash-es'
import { debounce, isEmpty } from 'lodash-es'
import { getContext } from 'svelte'
import Icon from 'svelte-awesome'
Expand All @@ -18,20 +17,33 @@
export let id = 'transform-modal-' + uniqueId()
export let json
export let selectedPath = []
/** @type {QueryLanguage[]} */
export let queryLanguages
/** @type {string} */
export let queryLanguageId
/** @type {(queryLanguageId: string) => void} */
export let onChangeQueryLanguage // TODO: implement a dropdown to change the selected query language
export let onTransform
export let indentation = 2
$: selectedJson = getIn(json, selectedPath)
const DEFAULT_QUERY = 'function query (data) {\n return data\n}'
function getSelectedQueryLanguage() {
// TODO: log a console warning when the queryLanguage is not found
return queryLanguages.find((item) => item.id === queryLanguageId) || queryLanguages[0]
}
const { close } = getContext('simple-modal')
const stateId = `${id}:${compileJSONPointer(selectedPath)}`
const state = transformModalState[stateId] || {}
let query = state.query || DEFAULT_QUERY
let query = state.query || getSelectedQueryLanguage().createQuery(json, {})
let previewHasError = false
let preview = ''
Expand All @@ -45,23 +57,14 @@
let sortDirection = state.sortDirection || null
let pickFields = state.pickFields || null
function evalTransform(json, query) {
// FIXME: replace unsafe new Function with a JS based query language
// As long as we don't persist or fetch queries, there is no security risk.
// TODO: only import the most relevant subset of lodash instead of the full library?
// eslint-disable-next-line no-new-func
const queryFn = new Function('_', `'use strict'; return (${query})`)(_)
return queryFn(json)
}
function updateQuery(newQuery) {
// console.log('updated query by wizard', newQuery)
query = newQuery
}
function previewTransform(json, query) {
try {
const jsonTransformed = evalTransform(json, query)
const jsonTransformed = getSelectedQueryLanguage().executeQuery(json, query)
preview = truncate(JSON.stringify(jsonTransformed, null, indentation), MAX_PREVIEW_CHARACTERS)
previewHasError = false
Expand All @@ -79,7 +82,7 @@
function handleTransform() {
try {
const jsonTransformed = evalTransform(selectedJson, query)
const jsonTransformed = getSelectedQueryLanguage().executeQuery(selectedJson, query)
onTransform([
{
Expand Down Expand Up @@ -127,13 +130,7 @@
<Header title="Transform" />
<div class="contents">
<div class="description">
Enter a JavaScript function to filter, sort, or transform the data.
</div>
<div class="description">
You can use <a href="https://lodash.com" target="_blank" rel="noopener noreferrer">Lodash</a>
functions like <code>_.map</code>, <code>_.filter</code>,
<code>_.orderBy</code>, <code>_.sortBy</code>, <code>_.groupBy</code>,
<code>_.pick</code>, <code>_.uniq</code>, <code>_.get</code>, etcetera.
{@html getSelectedQueryLanguage().description}
</div>

<div class="label">Path</div>
Expand Down Expand Up @@ -162,14 +159,15 @@
bind:pickFields
json={selectedJson}
onQuery={updateQuery}
createQuery={getSelectedQueryLanguage().createQuery}
/>
{:else}
(Only available for arrays, not for objects)
{/if}
{/if}

<div class="label">Query</div>
<textarea class="query" bind:value={query} />
<textarea class="query" spellcheck="false" bind:value={query} />

<div class="label">Preview</div>
<textarea class="preview" class:error={previewHasError} bind:value={preview} readonly />
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/modals/TransformWizard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import Select from 'svelte-select'
import { getNestedPaths } from '../../utils/arrayUtils.js'
import { stringifyPath } from '../../utils/pathUtils.js'
import { createQuery } from '../../logic/jsCreateQuery.js'
import { isEmpty, isEqual } from 'lodash-es'
export let json
export let onQuery
export let createQuery
// fields
export let filterField
Expand Down
12 changes: 12 additions & 0 deletions src/lib/components/modes/codemode/CodeMode.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@
/** @type {((text: string, previousText: string) => void) | null} */
export let onChange = null
/** @type {QueryLanguage[]} */
export let queryLanguages
/** @type {string} */
export let queryLanguageId
/** @type {(queryLanguageId: string) => void} */
export let onChangeQueryLanguage
export let onSwitchToTreeMode = () => {}
export let onError
export let onFocus = () => {}
Expand Down Expand Up @@ -273,6 +282,9 @@
json: json,
selectedPath,
indentation,
queryLanguages,
queryLanguageId,
onChangeQueryLanguage,
onTransform: onTransform
? (operations) => {
onTransform({
Expand Down
13 changes: 13 additions & 0 deletions src/lib/components/modes/treemode/TreeMode.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@
export let mainMenuBar = true
export let navigationBar = true
export let validator = null
/** @type {QueryLanguage[]} */
export let queryLanguages
/** @type {string} */
export let queryLanguageId
/** @type {(queryLanguageId: string) => void} */
export let onChangeQueryLanguage
export let visible = true
export let indentation = 2
export let onError
Expand Down Expand Up @@ -1148,6 +1158,9 @@
json: json,
selectedPath,
indentation,
queryLanguages,
queryLanguageId,
onChangeQueryLanguage,
onTransform: onTransform
? (operations) => {
onTransform({
Expand Down
1 change: 1 addition & 0 deletions src/lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const viteOptimizeDeps = [
'classnames',
'debug',
'diff-sequences',
'jmespath', // TODO: double check whether jmespath dep is necessary here
'json-source-map',
'natural-compare-lite'
]
2 changes: 2 additions & 0 deletions src/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export const JSONEditor = _JSONEditor

// plugins
export { createAjvValidator } from './plugins/createAjvValidator.js'
export { lodashQueryLanguage } from './plugins/query/lodashQueryLanguage.js'
export { jmespathQueryLanguage } from './plugins/query/jmespathQueryLanguage.js'

// utils
export const SortModal = _SortModal
Expand Down
Loading

0 comments on commit 030d3ca

Please sign in to comment.